我的应用程序中的许多类都使用了一些服务。例如,这可以是LoggerService
,它将消息记录到内部存储区并将其打印到控制台。
此服务可能如下所示:
export class LoggerService {
let _logs = [];
addLog(msg) {
this._logs.push(msg);
console.log(this._logs.length + ': ' + msg);
}
}
我猜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...');
}
}
基本上这种方法效果很好但是在更大范围内感觉有点“笨拙”,我希望它可以简化:
MyNamespace.LoggerService.addLog('blahblah');
之类的代码。我如何用Aurelia实现这一目标?是否有一种更直接的方式可以从命令行中获得更好的调试体验?
答案 0 :(得分:5)
诚实的回答?如果您遵循ES6模块化代码约定,而不是真的。如果需要,您将始终导入模块。有些事你可以做,我将在这个答案中讨论。
如果你不愿意,你实际上不需要使用Aurelia的依赖注入。但是,这意味着您必须自己处理对象的生命周期。因为您的对象是一个类,所以在导入它时必须在其上调用“new”。但是,您可以以不同方式编写日志记录模块,而不是导出类,可以导出函数,如下所示:
let _logs = [];
export var LoggerService = {
addLog: function (msg) {
_logs.push(msg);
console.log(_logs.length + ': ' + msg);
}
}
这样,你所要做的就是导入LoggerService并在Aurelia视图中调用LoggerService.addLog
而不必注入它。这是一种比类实例化方法更实用的方法,它可以很好地工作。
import {LoggerService} from 'LoggerService';
export class SomeViewModel {
constructor() {
}
somethingChanged() {
LoggerService.addLog('Something changed...');
}
}
你可以做的另一件事(我不推荐这个)就是把它变成一个窗口变量。这意味着您不必导入模块。但这违反了模块原则,事情很快就会变得混乱。模块存在是有原因的,尽管import语句确实添加了代码行,但是额外的空间也是值得的。
对于您的用例,我将使用上面基于函数的方法,并且我会在某处检查“development”标志,以便您可以在窗口对象上公开属性,以便您可以通过控制台访问它们。 (你不希望在生产环境中使用它,因为人们可能很容易弄乱你的应用程序。)像
这样的东西if (developmentFlag) { window.loggerService = LoggerService; }
在我们能够在控制台REPL中运行import
语句之前,这可能是最好的方法。