2015-05-08 75 views
1

这里的上下文是Backbone,但它是关于动态创建javascript对象的一般问题。动态创建JavaScript对象(Backbone View)

我想传递一个视图(“ViewX”)的名义创建,以一个功能,那么它可以调用视图的构造函数:new ViewX()

我怎么能这样做?

一些更多的上下文:

在我的骨干查看我想创建一个子视图,它的类型取决于我已经用于当前视图的模型。

目前我有一个非动态的if-else方法(请参阅示例中的方法1),但它有效,但在将来有更多模型类型时会变得笨重。

我已经尝试了一些动态的方法来创建子视图,包括通过函数构造函数(方法#2)给出'字符串不是函数'错误的评估。

在方法#3中,作为参数传递的View模块在当前视图的this命名空间(我正在使用requirejs)中不可用。

renderContentList: function() { 

    var self = this; 

    // Approach #1 
    var setSidebarListCollectionView = function(type) { 
     if (type === 'tags') { 
      self.sidebarListCollectionView = new TagSidebarListCollectionView({ 
       collection: self.collection, 
       tagCollection: self.tagCollection 
      }); 
     } else { 
      self.sidebarListCollectionView = new CardSidebarListCollectionView({ 
       collection: self.collection, 
       tagCollection: self.tagCollection 
      }); 
     } 
    }; 
    /* 
    // Approach #2 
    var setSidebarListCollectionView = new Function('type', 'coll', 'tagColl', 'return new type({collection: coll, tagCollection: tagColl});'); 

    // Approach #3 
    var setSidebarListCollectionView = function(type) { 
     return new self[type]({ 
         collection: self.collection, 
         tagCollection: self.tagCollection 
        }); 
    }; 
    */ 
    // reset it every time 
    if (this.sidebarListCollectionView) { 
     this.sidebarListCollectionView.remove(); 
    } 
    if (this.model.get('activeSubTab') === 'tags') { 
     // Approach #1 
     setSidebarListCollectionView('tags'); 
     // Approach #2 
     // this.sidebarListCollectionView = setSidebarListCollectionView('TagSidebarListCollectionView', this.collection, this.tagCollection); 
     // Approach #3 
     // this.sidebarListCollectionView = setSidebarListCollectionView('TagSidebarListCollectionView'); 
    } else { 
     // Approach #1 
     setSidebarListCollectionView('cards'); 
     // Approach #2 
     // this.sidebarListCollectionView = setSidebarListCollectionView('CardSidebarListCollectionView', this.collection, this.tagCollection); 
     // Approach #3 
     // this.sidebarListCollectionView = setSidebarListCollectionView('CardSidebarListCollectionView'); 
    } 

    // render the list of content title links. 
    this.$el.find('#content-manager-list-content').append(this.sidebarListCollectionView.render().el); 
}, 

我问这个问题了,在Stack Exchange Code Review,但也许因此是一个更好的选择。

回答

0

您可以通过扩展Backbone.Events来实现此目的。

1.创建一个扩展为Backbone.Events的控制器对象。
2.为每个视图创建定义自定义事件。
3.触发相应的自定义事件以创建视图。

var AppViewBus = _.extend({},Backbone.Events); 

AppViewBus.on("showview:ViewX",function(payload){ 
    // Load data if required. 
    // Create a view instance passing the loaded data. 
    // Render the view. 
}); 

AppViewBus.on("showview:ViewY",function(payload){ 
    // Load data if required. 
    // Create a view instance passing the loaded data. 
    // Render the view. 
}); 

无论您需要动态创建新视图,您都可以执行类似下面的操作,因为您已知道要创建的视图。

var payload = { 
    // Add properties that you probably require to pass 
    // down to your controller method 
}; 
AppViewBus.trigger("showview:ViewX",payload); 

您还可以重复使用从router callbacks这些方法也使您的代码的可重用性和可维护性。这一建议

+0

谢谢,这是有趣的 - 但我认为这是移动什么我已经在做的应用程序的不同部分。 – Lemmy