简体   繁体   English

Backbone.js-视图内的视图并重新渲染

[英]Backbone.js - views within views and re-renders

I have a collection of items and I am building a simple interface that lists the items on the left, then shows the detail of the currently selected item on the right. 我有一个项目集合,并且正在构建一个简单的界面,该界面在左侧列出这些项目,然后在右侧显示当前所选项目的详细信息。

I am trying to render a ItemView for each item within a ItemsListView. 我正在尝试为ItemsListView中的每个项目渲染一个ItemView。 I need to bind to the model's change event so that the ItemView is updated along with the ItemDetailView. 我需要绑定到模型的change事件,以便ItemView与ItemDetailView一起更新。

In my implementation below, when updating the model that is showing in the ItemDetailView, setting a new property on the model updates the ItemDetailView but not it's representation in the ItemView. 在下面的实现中,当更新显示在ItemDetailView中的模型时,在模型上设置新属性将更新ItemDetailView,但不会更新它在ItemView中的表示。 I know that I am doing something silly. 我知道我在做傻事。 How can I re-implement this so that both are re-rendered? 如何重新实现此功能,以便重新渲染两者?

PS I am trying to avoid re-rendering the List view every time. PS我试图避免每次重新呈现列表视图。 I'd like to re-render each ItemView in the list separately. 我想分别重新渲染列表中的每个ItemView。

var Item = Backbone.Model.extend({

});

var Items = Backbone.Collection.extend({

  model: Item

});

var ItemView  = Backbone.View.extend({

  template: window.JST['item/list'],

  initialize: function() {
    _.bindAll(this, 'render');
    this.model.bind('change', this.render);
  },

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

});

var ItemDetailView = Backbone.View.extend({

  el: $('.detail .grid'),

  template: window.JST['item/detail'],

  initialize: function() {
    _.bindAll(this, 'render');
    this.model.bind('change', this.render);
    this.render();
  },

  render: function() {
    $(this.el).html('').fadeOut('fast', function() {
      $(this.el).html(this.template(this.model.toJSON())).fadeIn();
    }.bind(this));
    return this;
  }

});

// for the Items collection
var ItemsView = Backbone.View.extend({

  el: $('.items ol.grid'),

  initialize: function() {
    _.bindAll(this, 'render');
  },

  render: function() {

    // need to put this as the first item in the list
    $(this.el).html('<li class="listHeader"></li>');

    // iterate over the collection and render each ItemView separately
    this.collection.each(function(l) {
      var lv = new ListView({ model: l, collection: this.collection });
      var html = lv.template(lv.model.toJSON());
      $(this.el).append(html);
    }.bind(this));
  }

});

I think the problem (maybe not the only one?) is that you haven't set the el property on ItemView , so it doesn't know how to render itself. 我认为问题(也许不是唯一的问题?)是您尚未在ItemView上设置el属性,因此它不知道如何呈现自身。 I'm not sure what the best way to fix this is. 我不确定解决此问题的最佳方法是什么。 Maybe add the client ID to the template using <li id='<#= cid #>' ... , and then in the initialize function of ItemView , set el using this.el = "#" + this.model.cid; 也许使用<li id='<#= cid #>' ...将客户端ID添加到模板中,然后在ItemViewinitialize函数中,使用this.el = "#" + this.model.cid;设置el this.el = "#" + this.model.cid; or something similar. 或类似的东西。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM