marionette.js vs Backbone更新DOM

时间:2014-11-05 04:11:00

标签: javascript jquery dom backbone.js marionette

我注意到Marionette与Backbone相比更新了DOM的方式。我创造了两个简单的小提琴。一个使用Backbone和另一个基于木偶。这两个示例都有一个辅助方法调用processDom,该方法只需在迭代50次后抛出一个错误。

然而,骨干示例元素已附加到DOM,直到die()方法触发。但在基于牵线木偶的示例中,DOM根本没有更新。如果有人可以解释这是如何工作的话会很棒。我想知道木偶内部使用的是一种虚拟的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/

1 个答案:

答案 0 :(得分:2)

一般用于后期处理,您可以使用onRender Marionette.ItemView。重写Marionette.ItemView.render不是一个好习惯。

Marionette区域内的Backbone区域内的视图渲染处理方式略有不同。

当您渲染Backbone.View时,您的元素会将自身附加到DOM的$('#search-container'),并且在render方法中,它将使用已附加的元素进行操作,以便您可以看到更改。

当您使用Marionette.ItemView方法呈现Marionette.Region.show时,Marionette.Region已经附加到DOM并且需要呈现适当的视图(在您的情况下为ItemView)并且仅在此之后步骤它会将它附加到DOM并将ItemView设置为currentView

您可以从Marionette.Region.show的{​​{3}}看到它在render被调用后附加了视图。在您的情况下,render将抛出错误,它将永远不会附加到DOM。


要深入理解它,请查看负责在BackboneView中附加/创建视图的2个方法。 Marionette对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;
},

正如你从评论中看到的那样,所有魔法都在几行代码中,这就是我喜欢它的原因。