2015-05-08 124 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