【问题标题】:marionette.js vs Backbone updating DOMmarionette.js 与 Backbone 更新 DOM
【发布时间】:2014-11-05 04:10:59
【问题描述】:

我注意到与 Backbone 相比,Marionette 更新 DOM 的方式有所不同。我创建了两个简单的小提琴。一种使用 Backbone,另一种基于 Marionette。这两个示例都有一个辅助方法调用 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/

【问题讨论】:

    标签: javascript jquery dom backbone.js marionette


    【解决方案1】:

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

    Marionette 区域内视图的渲染处理与 Backbone 情况略有不同。

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

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

    您可以从Marionette.Region.showsource 看到它在调用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;
    },
    

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

    【讨论】:

    • 很好的答案@vahan-vardanyan。这是否意味着如果我正确使用 Marionette,我不需要使用 documentFragment 来克服主干应用程序中的一个常见问题,即大量 DOM 修改?当嵌套视图太多时,大量的 DOM 修改成为一个问题。这个问题也在link中讨论过在渲染集合时导致多个DOM回流部分
    • 很棒的文章。是的!对于集合渲染,Marionette 将使用该技术。您可以签出源代码并在那里看到 documentFragment。
    猜你喜欢
    • 2016-03-07
    • 1970-01-01
    • 2013-04-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-22
    • 2019-02-15
    • 1970-01-01
    相关资源
    最近更新 更多