【问题标题】:Updating a view in backbone when a collection is updated更新集合时更新主干中的视图
【发布时间】:2013-07-02 14:52:40
【问题描述】:

我有一个正在构建的网络应用程序,我有一个表单输入,允许您输入一个名称,在输入这​​个名称时,我想用输入的名称更新一个列表,但是我的问题是,如果添加一个名称然后另一个输出到视图的 previos 名称被覆盖(但如果我刷新页面,我会得到完整列表)。这是我的代码,

GroupModalHeaderView.prototype.render = function() {
  this.$el.empty();
  if (this.model.isNew()) {
    this.$el.append(this.template({
      m: this.model.toJSON()
    }));
    return this.edit();
  } else {
    this.$el.append(this.template({
      m: this.model.toJSON()
    }));
    this.$el.find(".modal-header-menu").show();
    return this.$el.find(".icon-button-close-modal").show();
  }
};



GroupModalHeaderView.prototype.save = function(e) {
      var $collection, $this;
      if (e) {
        e.preventDefault();
      }
      $this = this;
      if (this.$("#group-name").val() !== "") {
        $collection = this.collection;
        if (this.model.isNew()) {
          this.collection.push(this.model);
        }
        return this.model.save({
          name: this.$("#group-name").val(),
          async: false,
          wait: true
        }, {
          success: function() {
            return $this.cancel();
          }
        });
      }
    };

GroupListView.prototype.events = {
      "click .list-header-add": "add",
      "click .list-header-expander": "showHide",
      "keyup #search-query": "keyup"
    };

    GroupListView.prototype.initialize = function() {
      //console.log("fired");
      this.collection.on("change", this.renderList, this);
      this.collection.on("reset", this.render, this);
      return this.renderList();
    };

GroupListView.prototype.renderList = function(collection) {
      var responsiveHeight = $("body").height() - 400;
      if($("#people-network-requests").is(":visible")) {
        this.$el.find("#people-groups-list").height($("#people-people-list").height()-250+"px");
      } else {
        this.$el.find("#people-groups-list").height($("#people-people-list").height()+"px");
      }
      var $collection, $this;
      if (!collection) {
        collection = this.collection;
      }
      this.$el.find(".list-items").empty();
      $this = this.$el.find("#people-groups-list");
      this.$el.find(".list-items").removeClass("list-items-loading").empty();
      $collection = collection;
      if ($collection.length < 1) {
        /*this.$el.find("#people-groups-inner").hide();
        $(".activity-no-show").remove();
        return this.$el.find("#people-groups-inner").append('<div class="activity-no-show">\
        <p>To add a new group, click the + in the top right hand corner to get started.</p>\
        </div>');*/
      } else {
        this.collection.each(function(item) {
          var displayView;
          displayView = new app.GroupListDisplayView({
            model: item,
            collection: $collection
          });
          console.log($this);
          return $this.append(displayView.render());
        });
        return this;
      }
    };

    return GroupListView;

  })(app.BaseView);

GroupListDisplayView.prototype.render = function() {
      //console.log(this.$el);
      //alert("1");
      var $body;
      this.$el.html(this.template({
        m: this.model.toJSON()
      }));
      $body = this.$el.find(".card-body");
      $text = $body.text();
      $.each(this.model.get("people"), function(i, person) {
        var personTile;
        this.person = new app.Person({
          id: person.id,
          avatar: person.avatar,
          first_name: person.first_name,
          last_name: person.last_name
        });
        personTile = new app.PersonTileView({
          model: this.person
        });
        if(person.id) { 
          $body.append(personTile.render()).find(".instruction").remove();
        }
      });
      return this.$el.attr("id", "group-card-" + this.model.id);
    };

GroupListView.prototype.keyup = function() {
      this.filtered = $collection.searchName(this.$el.find("#search-query").val());
      //console.log(this.filtered);
      return this.renderList(this.filtered);
    };

【问题讨论】:

  • 只是好奇,你为什么使用原型而不是Backbone.View.extend?
  • 继承的代码,项目目前还不能重构,所以我暂时坚持以前的开发人员所做的事情

标签: javascript backbone.js underscore.js backbone.js-collections


【解决方案1】:
this.collection.on("add", this.addDisplayView, this);

然后创建一个接受视图模型的函数addDisplayView。您需要重构代码的 this.collection.each(function(item)... 部分以使用 addDisplayView 函数。

GroupListView.prototype.addDisplayView = function(model){
    var displayView = new app.GroupListDisplayView({
        model: model,
        collection: this.collection
    });
    // use this.$, as it is already mapped to the context of the view
    return this.$("#people-groups-list").append(displayView.render());
}

您还应该将this.collection.push(this.model); 更改为this.collection.add(this.model);

addcollection.add(models, [options])

将模型(或模型数组)添加到集合中,触发“添加”事件。如果一个模型属性 已定义,您还可以传递原始属性对象,并让它们成为 活生生地作为模型的实例。通过 {at: index} 拼接 模型到指定索引处的集合中。如果您要添加 模型到已经在集合中的集合,它们将 被忽略,除非你通过 {merge: true},在这种情况下他们的 属性将被合并到相应的模型中,触发任何 适当的“改变”事件。

http://documentcloud.github.io/backbone/#Collection-add

【讨论】:

  • addDisplayView 实际上做了什么——我已经有一个构建视图的函数
  • GroupListView.prototype.addDisplayView 将用于创建 DisplayView。我会模拟一些东西。
  • 谢谢 - 我在添加集合时也运行它,但它仍然会覆盖最后输入的名称,直到我刷新页面,这几乎就像我添加到一个集合然后从另一个完全不同的集合中读取一。
  • 是的,如果我在添加第一个名称后添加另一个名称,this.collection.on("change") 或 this.collection.on("add" are not fire) 就是这个可能的?为什么 this.collection.on 不会触发?
  • 我正在查看代码...我对你有感觉。你有小提琴或其他东西来展示它吗?我认为您的问题是您正在使用 this.collection.push(this.model);改成this.collection.add(this.model);
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-02
  • 1970-01-01
  • 2023-03-13
  • 2012-10-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多