如何在Aurelia中最好地使用全球服务类

sua*_*kim 2 aurelia

我有一些服务,我的应用程序中的许多类使用.例如,这可以是LoggerService将消息记录到内部存储并将其打印到控制台的示例.

这项服务看起来像这样:

export class LoggerService {
    let _logs = [];

    addLog(msg) {
        this._logs.push(msg);
        console.log(this._logs.length + ': ' + msg);
    }
}
Run Code Online (Sandbox Code Playgroud)

我想在Aurelia中通常的方法是使用这个带有依赖注入的类,因为它默认使用单例,因此工作得很好.然后,示例用法可能如下所示:

import {autoinject, Aurelia} from 'aurelia-framework';
import {LoggerService} from 'LoggerService';

@autoinject
export class SomeViewModel {
    let _loggerService;

    constructor(loggerService) {
        this._loggerService = loggerService
    }

    somethingChanged() {
        this._loggerService.addLog('Something changed...');
    }
}
Run Code Online (Sandbox Code Playgroud)

基本上这种方法工作得很好但是在更大的范围内感觉有点"笨拙",我希望它可以简化:

  • 使用依赖注入需要在每个"使用类"中使用大量的样板代码,这些代码不必要地"膨胀"它们(import语句,需要在构造函数中分配的专用类成员等).
  • 我习惯将这些类放在一个存在于window对象中的专用命名空间中.这使我可以方便地调试,因为我可以MyNamespace.LoggerService.addLog('blahblah');直接从命令行调用代码.我如何通过Aurelia实现这一目标?

有没有更直接的方法,这也可以从命令行给我一个更好的调试体验?

jed*_*ung 5

诚实的回答?如果您遵循ES6模块化代码约定,而不是真的.如果需要,您将始终导入模块.有些事你可以做,我将在这个答案中讨论.

如果你不想,你实际上不需要使用Aurelia的依赖注入.但是,这意味着您必须自己处理对象的生命周期.因为您的对象是一个类,所以在导入它时必须在其上调用"new".但是,您可以以不同方式编写日志记录模块,而不是导出类,可以导出函数,如下所示:

let _logs = [];

export var LoggerService = {
    addLog: function (msg) {
        _logs.push(msg);
        console.log(_logs.length + ': ' + msg);
    }
}
Run Code Online (Sandbox Code Playgroud)

这样,你所要做的就是导入LoggerService并调用LoggerService.addLog你的Aurelia视图,而不必注入它.这是一种比类实例化方法更实用的方法,它可以很好地工作.

import {LoggerService} from 'LoggerService';

export class SomeViewModel {    
    constructor() {
    }

    somethingChanged() {
        LoggerService.addLog('Something changed...');
    }
}
Run Code Online (Sandbox Code Playgroud)

你可以做的另一件事(我不推荐这个)就是把它变成一个窗口变量.这意味着您不必导入模块.这违反了模块原则,事情很快就会变得混乱.模块存在是有原因的,虽然import语句确实添加了代码行,但是额外的空间也是值得的.

对于您的用例,我将使用上面基于函数的方法,我会在某处检查"development"标志,以便您可以在窗口对象上公开属性,以便您可以通过控制台访问它们.(你不希望在生产环境中使用它,因为人们可能很容易弄乱你的应用程序.)类似的东西

if (developmentFlag) { window.loggerService = LoggerService; }
Run Code Online (Sandbox Code Playgroud)

在我们能够import在控制台REPL中运行语句之前,这可能是最好的方法.