2013-11-22 28 views
0

我们的店最近刚刚采用了Backbone,甚至给了我绿灯试用Marionette。然而,后者并没有给我带来希望的负担(可能是由于我的无知),所以我试图设计一个轻量级的依赖注入系统,其中所有的Backbone视图都获得了一个“应用程序“我自己设计的对象。为Backbone.js app设计依赖注入系统的范围界定问题

我的系统基于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

@mu太短,和/或任何其他人打算建议基本观点。应用程序是App的入口点。我如何获得一个*初始化*应用程序到BaseView,所以扩展视图可以访问应用程序?这不会要求BaseView在运行时延长*吗? “也许我错过了一些明显的东西”,但在运行时注入依赖关系并不是那么简单吗? –

回答

0

这是另一个可以说是更好的办法;继承甚至有可能。正如所演示的那样,这对我来说尤其重要。感谢this fine answer关于如何通过调用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)(); 
    } 
); 
1

我简化了一些事情,并获得了以下“工作”。然而,我想分配view.instantiator回来查看,而我不能去工作:(肯定会接受别人的答案,如果他们可以让我最后可以简单地调用“新的MyView()”并访问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); 

//输出:“棒”乘以2