2

我一直在使用 javscript 进行依赖注入,但有一些问题需要帮助

一个简单的例子是我有一个对话框模块,在页面上的多个地方使用,当用户与页面上的组件交互时,它会通过自定义消息提醒用户

function Dialog () {

}

Dialog.prototype.show = function () {

}

这可以用在一个组件中,比如一个验证用户搜索的搜索控件,如果它为空,它会触发一个错误对话框。使用依赖注入我假设我会写:

function searchComponent (dialog) {
   this.dialog = dialog
}

searchComponent.prototype.validateSearch = function () {
    // validate search if invalid create error
    this.dialog.show();
}

var searchDialog = new Dialog();
var search = new searchComponent(searchDialog);

然而,用户可能永远不需要搜索错误对话框,但我正在创建它的一个实例,以便我可以传递依赖关系,如果我在页面上有 100 个单独的对话框实例,我会构造这 100 次吗?这在性能上是不必要且昂贵的。

我宁愿做的是将对话框的构造延迟加载到需要的时候

searchComponent.prototype.validateSearch = function () {
  //validate search if invalid create error
  var dialog = new Dialog();
  dialog.show();
}

现在我知道这会造成不利影响,其中之一是它对单元测试的影响,我很想了解我是否错过了某些东西或替代方法?

提前致谢

4

4 回答 4

7

JavaScript 函数是第一类对象。不是传入构造的对话框,而是传入对话框构造函数:

var search = new SearchComponent(Dialog);

然后在你需要的时候更新它:

function SearchComponent(Dialog) {
  this.Dialog = Dialog;
}

SearchComponent.prototype.validateSearch = function() {
  var dialog = new this.Dialog();
  dialog.show();
}
于 2013-03-03T19:25:49.130 回答
1

受前面示例的启发,我创建了一个简单的jsFiddle ,它利用一个名为Syringe.js的小型库来展示如何通过预绑定SearchComponent构造函数来注入依赖项。

创建SearchComponent对象时,validator会自动提供依赖项(一个单独的组件,这里代替实际的对话框)。该依赖关系随后被该validateSearch方法使用。

SearchComponent这样做的好处是,当您创建每个对象实例时,您不必手头有任何依赖项。

此外,可以在创建对象validator后修改依赖关系SearchComponent,并且可以相应地更新依赖控件的行为。

于 2013-05-15T20:52:13.467 回答
1

要扩展@ChrisTavares 的出色解决方案,您也可以使用类似这样的方法在Dialog可能的内部进行依赖注入:

var foo = function () { return new Foo() }; // just an example
var search = new SearchComponent(function() {
    return new Dialog(foo());
});

在你的内部SearchComponent

function SearchComponent(Dialog) {
    this.Dialog = Dialog;
}

SearchComponent.prototype.validateSearch = function () {
    var dialog = new this.Dialog();
    dialog.show();
};
于 2013-03-03T19:29:42.533 回答
0

我最近编写了一个名为 infect.js 的依赖注入库。看看吧,可能正是你要找的。https://github.com/amwmedia/infect.js

于 2013-11-17T18:08:29.937 回答