2013-02-14 62 views
1

我有骨幹以下的問題,我想知道什麼樣的策略是更多的撥款重新呈現骨幹觀點不失引用DOM

我有一個選擇控制,作爲骨幹觀點,認爲最初加載實現用一個選項說「加載選項」。所以我加載只有一個元素的數組,並呈現視圖。

選項將從集合中加載,所以我啓動了一個提取集合。

然後,我初始化一個組件負責顯示每個字段的行錯誤。所以我保存了組合的dom元素的引用。

當獲取操作終於準備就緒時,我重新提交從集合中加載的所有選項的控件。

渲染視圖我的用戶是這樣的:

render: function() { 
    this.$el.html(this.template(this.model.attributes)); 
    return this; 
} 

相當標準的骨幹東西

問題是渲染視圖第二次以後的DOM的引用不再有效。 ,

也許這種情況有點奇怪,但我可以想到很多情況下,我必須重新渲染一個視圖而不丟失它們的doms引用(例如,取決於另一個組合的組合)

所以我不知道什麼是重新渲染視圖,而不會丟失所有引用視圖內的DOM元素的最佳途徑......

+0

我的2美分...你不應該直接使用model.attributes,這就是爲什麼你有model.get('something')和model.set('something',value)或model.set({some: a,thing:b})。 – 2013-02-16 14:37:08

+0

使用model.attributes只能閱讀它有什麼問題?我明白爲什麼我應該使用Model#Set(觸發更改事件和其他內容),但Model#Get沒有多大作用。看看代碼,它只是一個:return this.attributes [attr]; – opensas 2013-02-16 17:43:53

+1

而且,據我所見,沒有model.getAll()。 model.attributes似乎是唯一的方法來做到這一點。 – morewry 2013-02-27 16:33:36

回答

5

Backbone.View目的是封裝獲得了一定DOM樹到一個明確定義的類。這是一個糟糕的Backbone實踐來傳遞DOM元素的引用,這些應該被視爲視圖的內部實現細節。

相反,您應該讓自己的意見直接溝通,或通過中介間接溝通。

直接通信可能看起來像:

var ViewA = Backbone.View.extend({ 
    getSelectedValue: function() { 
    return this.$(".combo").val() 
    } 
}); 

var ViewB = Backbone.View.extend({ 
    initialize: function(options) { 
    this.viewA = options.viewA; 
    }, 
    doSomething: function() { 
    var val = this.viewA.getSelectedValue(); 
    } 
}); 

var a = new ViewA(); 
var b = new ViewB({viewA:a}); 

和間接使用root Backbone對象作爲調解人:

var ViewA = Backbone.View.extend({ 
    events: { 
    "change .combo" : "selectedValueChanged" 
    }, 
    selectedValueChanged: function() { 
    //publish 
    Backbone.trigger('ViewA:changed', this.$('.combo').val()); 
    } 
}); 

var ViewB = Backbone.View.extend({ 
    initialize: function(options) { 
    //subscribe 
    this.listenTo(Backbone, 'ViewA:changed', this.doSomething); 
    }, 
    doSomething: function(val) { 
    //handle 
    } 
}); 

var a = new ViewA(); 
var b = new ViewB(); 

以上是非常通用的,當然,但有一點我這裏試圖說明的是,你不必擔心DOM元素是否被交換過,因爲沒有其他視圖應該知道元素的存在。如果您定義視圖之間的接口(通過方法調用或中介消息傳遞),您的應用程序將更易於維護,並且不易碎。

+0

優秀答案fencliff !!!這應該在backbone.js視圖的定義中是正確的。我認爲這些(不那麼)概念化的東西是使骨幹難以開始的東西。 – opensas 2013-02-14 15:11:34

+0

因此,作爲一般規則,我應該只使用對圓頂元素的引用: 1.在構造函數中傳遞el元素時。 2.從視圖本身引用任何dom子樹元素(我想我也應該覆蓋View#setElement來更新所有內部引用)。 3. NOWHERE ELSE - 這樣我就可以在渲染時不必擔心破損的dom引用(實際上,視圖應該照顧更新它們的內部引用),從而每次都可以銷燬dom視圖並重新生成它。 你是否同意這樣的規則? – opensas 2013-02-14 15:22:24