动态创建javascript对象(Backbone View)

时间:2015-05-08 09:07:24

标签: javascript backbone.js requirejs

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

我想将要创建的View(' ViewX')的名称传递给可以调用View构造函数的函数:new ViewX()

我怎么能这样做?

更多背景信息:

在我的Backbone View中我想创建一个子视图,其类型取决于我用于当前视图的模型。

目前,我有一个非动态的if-else方法(参见示例中的方法#1),但是很笨重,将来当我有更多模型类型时会更加笨重。

我尝试了一些动态方法来创建子视图,包括通过Function构造函数(方法#2)进行评估,这使得' string不是一个函数'错误。

在方法#3中,我作为参数传递的View模块在当前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提出了这个问题,但也许SO更适合它。

1 个答案:

答案 0 :(得分:0)

One way you can achieve this is by making extending left join.

1.Create a controller object that extends SELECT a.*, b.id is not null as condition_check FROM TableA a LEFT JOIN TableB b ON a.Id = b.Id .
2.Define custom events for each view creation.
3.Trigger the appropriate custom event to create a view.

Backbone.Events

Now wherever you need to create a new view dynamically you can do something like below since you already know what view you want to create.

Backbone.Events

You can also reuse these methods from the 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. }); too making your code more reusable and maintainable.