我一直在玩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();
}
现在我知道这会产生不利之处,其中一个就是它对单元测试的影响,我很想知道的是我是否遗漏了某些东西或者替代方法?
提前致谢
答案 0 :(得分:7)
JavaScript函数是第一类对象。不是传入构造的对话框,而是传入对话框构造函数:
var search = new SearchComponent(Dialog);
然后在需要时重启:
function SearchComponent(Dialog) {
this.Dialog = Dialog;
}
SearchComponent.prototype.validateSearch = function() {
var dialog = new this.Dialog();
dialog.show();
}
答案 1 :(得分: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();
};
答案 2 :(得分:1)
受前面示例的启发,我创建了一个简单的jsFiddle,它利用一个名为Syringe.js的小型库,以显示如何通过预绑定SearchComponent
来注入依赖项构造
创建SearchComponent
对象时,会自动配置validator
依赖项(一个单独的组件,此处取代实际对话框)。随后validateSearch
方法使用此依赖关系。
以这种方式执行此操作的优点是,在创建每个SearchComponent
对象实例时,您不必拥有任何依赖项。
此外,可以在创建validator
对象后修改SearchComponent
依赖项,并且可以相应地更新从属控件的行为。
答案 3 :(得分:0)
我最近编写了一个名为infect.js的依赖注入库。看看,可能就是你想要的。 https://github.com/amwmedia/infect.js