我们的商店刚刚采用了Backbone,甚至还给了我试用木偶的绿灯。然而,后者并没有给我带来的好处(可能是由于我的无知),所以我试图设计一个轻量级的依赖注入系统,我的所有Backbone视图都获得了一个“应用程序”的实例“我自己设计的对象。
我的系统基于a (necro) answer I posted yesterday,以下是适合我的代码。但是,我不希望在injectViewsWithApp
函数内为每个视图都有重复的代码块,而是希望循环遍历视图。但这是我无法弄清楚如何在循环内部工作的地方,我认为这是某种范围问题。
我将继续努力,以便在周末开始前的剩余时间内发布代码更新。
define(['backbone', './app/views/searchform', './app/views/searchresults', './app/views/FooBardetailrow'],
function(Backbone, SearchFormView, SearchResultsView, FooBarDetailRowView) {
var APP = initApp();
injectViewsWithApp();
launchApp();
function initApp() {
return {
collections : { // No need for separate files/modules if each view gets injected with the APP
extendedHaulFooBars : new (Backbone.Collection.extend({})),
stn333sts : new (Backbone.Collection.extend({})),
FooBarTypes : new (Backbone.Collection.extend({})),
FooBarSymbols : new (Backbone.Collection.extend({})),
FooBarSearchParams : new (Backbone.Collection.extend({}))
},
defaultModel : Backbone.Model.extend({}),
views : {}
};
}
function injectViewsWithApp() {
SearchFormView.instantiator = SearchFormView.extend({
initialize : function() {
this.app = APP;
SearchFormView.prototype.initialize.apply(this, arguments);
}
});
SearchResultsView.instantiator = SearchResultsView.extend({
initialize : function() {
this.app = APP;
SearchResultsView.prototype.initialize.apply(this, arguments);
}
});
FooBarDetailRowView.instantiator = FooBarDetailRowView.extend({
initialize : function() {
this.app = APP;
FooBarDetailRowView.prototype.initialize.apply(this, arguments);
}
});
}
答案 0 :(得分:1)
我简化了一些事情并获得了以下“工作”。但是,我想将view.instantiator分配回视图,这我无法开始工作:(如果他们可以做到这一点,肯定会接受别人的答案,最后我可以简单地调用“new MyView()”并且可以访问APP / app - 否则我认为以下情况并不是那么糟糕。
var APP = {foo : 'bar'};
var MyView = Backbone.View.extend({});
var views = [MyView];
for (var i=views.length; i--; ) {
var view = views[i];
view.instantiator = view.extend({
initialize : function() {
this.app = APP;
view.prototype.initialize.apply(this, arguments);
}
});
console.log(new view.instantiator().app.foo);
}
console.log(new MyView.instantiator().app.foo);
// OUTPUT:'bar'乘以2
答案 1 :(得分:0)
这是另一个可以说是更好的方式;正如所展示的那样,继承甚至是可能的,这在我的案例中尤其重要。感谢this fine answer如何保留' app'跨调用ParentView和ChildView模块。
define(['backbone'],
function(Backbone) {
var APP = {
foo : 'bar'
};
var MyParentView = (function() {
var app;
return function() {
return {
ctor : Backbone.View.extend({
initialize : function() {
this.app = app;
}
}),
inject : function(_app) {app = _app;}
}
}
})();
var MyChildView = (function() {
var app;
return function() {
return {
ctor : MyParentView().ctor.extend({
initialize : function() {
console.log(this.app); // OUTPUT: undefined
MyParentView().ctor.prototype.initialize.apply(this, arguments);
console.log(this.app.foo); // OUTPUT: bar
}
}),
inject : function(_app) {app = _app;}
}
}
})();
var injectableViews = [MyParentView, MyChildView];
for (var i = injectableViews.length; i--; ) {
injectableViews[i]().inject(APP);
}
new (MyChildView().ctor)();
}
);