【问题标题】:backbonejs render parentview without rendering children again on parent model change主干js渲染父视图而不在父模型更改时再次渲染子视图
【发布时间】:2019-07-04 19:56:58
【问题描述】:

我在带有嵌套集合的主干js 中面临一些架构问题。我有模型集合,每个模型内部都可以包含与儿童相同的模型集合。所以在父视图渲染中,我正在渲染子集合并将其 dom 附加到父视图。它工作得很好。

但是在父模型更改时,我正在重新渲染导致其子模型再次渲染的视图。但是当父母模型发生变化时,我不会创建儿童 dom,因为子集合没有变化。我可以在不重新渲染的情况下使用儿童 dom。有什么方法可以实现吗?

家长查看代码:

RowView.prototype.initialize = function(options) {
      this.childCollection = options.childCollection;
      this.listenTo(this.model, "change", this.render);
}
RowView.prototype.render = function() {
        var existingControls = this.model.get("controls").toJSON();
        this.childCollection = this.model.get("controls");
        this.childCollection.bind('add', this.addOneChild, this);
        this.childCollection.bind('reset', this.resetChildrens, this);
        this.childCollection.reset(existingControls, this);
    };
   RowView.prototype.addOneChild = function(respModel) {
      view = new RowViewChildView({
        model: respModel,
        parentView: this
      });

     this.$el.find('.childrens').append(view.render().el);
    };

   RowView.prototype.resetChildrens = function(currentCollection) {
      this.$el.find(".childrens").html('');
      return this.addAllChildrens();
    };

    RowView.prototype.addAllChildrens = function() {
      return this.childCollection.each(this.addOneChild, this);
    };

我也不想放弃子视图事件。

提前致谢

【问题讨论】:

    标签: backbone.js


    【解决方案1】:

    很遗憾,我还不能发表评论,所以我会创建一个答案。

    我不完全确定您想要实现什么,因为您的渲染方法看起来只包含用于渲染子级的代码而没有特定于渲染父级的代码,您是否忽略了这一点?

    但是,您可以尝试使用渲染和重新渲染功能。 rerender 函数只会渲染父 DOM 中已更改的部分(父标记下的所有内容)。

    render: function () {
        //render everything below .parent
    }
    rerender: function () {
        //render stuff below parent-mark-up
    }
    

    HTML 可以拆分

    <div class="parent">
     <div class="parent-markup"></div>
     <div class="children"></div>
    </div>
    

    如果您确实需要渲染整个父元素并希望重用子 DOM,您可以保护 el,然后再次附加它,然后使用 this.delegateEvents(); 确保事件 a 再次冒泡。

    一般我会将监听器放入初始化函数中,建议使用 this.listenTo(this.childCollection , 'add', this.callback);

    Backbonejs: .on vs .listenTo vs .bind

    最后我会推荐使用模块化语法这样的

    var RowView = Backbone.View.extend({
        initialize: function(options) {}
        render: function() {}
    });
    

    更新:这是一个小提琴:https://jsfiddle.net/gs4r8k10/30/

    【讨论】:

    • 嗨罗宾.. 感谢您的回答,但我的问题是,在更改父模型时,它正在渲染其视图,同时也渲染子视图。如果父模型发生变化,我不想渲染 childview。我想重用 childview dom,因为它的渲染非常昂贵
    • 但是您可以将this.listenTo(this.model, "change", this.render); 更改为this.listenTo(this.model, "change", this.rerender); 然后在rerender 中只更新父dom 而不更新子dom?或者您可以(如上所述)保存每个孩子的el,然后再次附加ist 并调用this.delegateEvents();
    • 嗨,我正在保存 el 的子元素,但是当我附加并调用 this.delegateEvents() 时,子事件不起作用。
    【解决方案2】:

    您可以使用 jQuery detach() 分离现有的子 DOM,并在父重新渲染后再次附加它们。

    如果可以像

    if(this.childrenAlreadyRendered){
      // special performant rendering with detach
    }
    

    在您的 render 方法中。 做了这么智能的渲染。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-09-18
      • 1970-01-01
      • 2023-03-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多