2014-11-05 149 views
1

我注意到有一個不同的方式,DOM被Marionette和Backbone更新的方式。我創造了兩個簡單的小提琴。一個使用Backbone,另一個使用基於牽線木偶的。這兩個示例都有一個輔助方法調用processDom,並且該方法在迭代50次後只是拋出一個錯誤。marionette.js vs骨幹更新DOM

然而,在骨幹示例中,元素被添加到DOM直到die()方法觸發。但在基於木偶的例子中,DOM並沒有被更新。如果有人能解釋這是如何工作的,那將是非常好的。我不知道木偶在內部使用了一種虛擬技術。

渲染在提線木偶示例方法

render: function() { 
      var viewHtml = this.template({ 
       'contentPlacement': 'Sydney' 
      }); 
      this.$el.html(viewHtml); 
      this.processDom(this.$el); 
      this.postRender(); 
     } 

渲染在骨幹示例方法

render: function() { 
     var template = Handlebars.compile($('#sample-template').html()); 
     var viewHtml = template({ 
       'contentPlacement': 'Sydney' 
      }); 
     this.$el.html(viewHtml); 
     this.processDom(this.$el); 
     this.postRender(); 
    }, 

鏈接撥弄例子

http://jsfiddle.net/samitha/v5L7c2t5/7/

http://jsfiddle.net/samitha/pc2cvmLs/7/

回答

2

一般爲了後處理目的,您可以使用 Marionette.ItemView。重寫Marionette.ItemView.render不是一個好習慣。

Marionette區域內渲染視圖的處理方式與Backbone的情況有所不同。

當您渲染Backbone.View - 您的元素將自己附加到DOM的$('#search-container'),並且在render方法中,它將使用已連接的元素進行操作,以便您可以看到更改。

當你與Marionette.Region.show方法渲染Marionette.ItemViewMarionette.Region已經連接到DOM,它需要渲染相應的視圖(在你的情況ItemView),只有這一步後,將其附加到DOM,並設置ItemViewcurrentView

你可以從sourceMarionette.Region.show看到它在調用render之後附加視圖。在你的情況下,render會拋出錯誤,它將永遠不會附加到DOM。


要理解它更深層次的讓我們來看看2種方法分別負責安裝/創造BackboneView意見。木偶使用相同的方法Marionette.ItemView

_ensureElement: function() { 
    if (!this.el) { // case when el property not specified in view 
    var attrs = _.extend({}, _.result(this, 'attributes')); 
    if (this.id) attrs.id = _.result(this, 'id'); 
    if (this.className) attrs['class'] = _.result(this, 'className'); 
    // creating new jQuery element(tagNam is div by default) with attributes specified 
    var $el = Backbone.$('<' + _.result(this, 'tagName') + '>').attr(attrs); 
    this.setElement($el, false); 
    } else { // case when el property exists 
    this.setElement(_.result(this, 'el'), false); 
    } 
} 

而且

setElement: function(element, delegate) { 
    if (this.$el) this.undelegateEvents(); 
    // here is all magic 
    // if element is instance of Backbone.$, which means that el property not specified 
    // or it's already jquery element like in your example(el: $('#search_container')) with Backbone. 
    // this.$el will be just a jQuery element or already attached to the DOM jQuery element 
    // in other case it will try to attach it to the DOM. 
    this.$el = element instanceof Backbone.$ ? element : Backbone.$(element); 
    this.el = this.$el[0]; 
    if (delegate !== false) this.delegateEvents(); 
    return this; 
}, 

正如你可以看到所有的評論神奇的是在幾行代碼,這就是爲什麼我喜歡它。

+0

偉大的答案@ vahan-vardanyan。這是否意味着如果我正確使用Marionette,我不需要使用** documentFragment **來克服骨幹應用程序中的一個常見問題,這個問題是繁重的DOM修改?有很多嵌套視圖時,重型DOM修改會成爲問題。這個問題也在[link](http://ozkatz.github。io/avoid-common-backbonejs-pitfalls.html)在部分**渲染集合時導致多個DOM重排** – fernando 2014-11-05 21:38:10

+0

偉大的文章。是!對於收集渲染,Marionette將使用該技術。您可以簽出源代碼並在那裏看到documentFragment。 – 2014-11-06 04:37:49