Backbone fetch добавя нови редове за преглед, вместо да актуализира съществуващите

Все още изучавам Backbone, но разбирам, че трябва да се справи с автоматичното актуализиране на изгледа в тази ситуация. Моят първичен индексен изглед е таблица, в която всеки ред е изглед на един модел.

index_view:

Tracker.Views.Friends ||= {}

class Tracker.Views.Friends.IndexView extends Backbone.View
  template: JST["backbone/templates/friends/index"]

  initialize: () ->
    _.bindAll(this, 'addOne', 'addAll', 'render');

    @options.friends.bind('reset', this.addAll);

  addAll: () ->
    @options.friends.each(this.addOne)

  addOne: (chaser) ->
    view = new Tracker.Views.Friends.FriendView({model : friend})
    this.$("tbody").append(view.render().el)

  render: ->
    $(this.el).html(this.template(friends: this.options.friends.toJSON() ))
    @addAll()

    return this

модел и колекция:

class Tracker.Models.Friend extends Backbone.Model
  paramRoot: 'friend'

  defaults:
    name: null
    status: null

class Tracker.Collections.FriendsCollection extends Backbone.Collection
  model: Tracker.Models.Friend
  url: '/friends.json'

приятелски изглед:

Tracker.Views.Friends ||= {}

class Tracker.Views.Friends.FriendView extends Backbone.View
  template: JST["backbone/templates/friends/friend"]

  events:
    "click .destroy" : "destroy"

  tagName: "tr"

  destroy: () ->
    @options.model.destroy()
    this.remove()

    return false

  render: ->
    $(this.el).html(this.template(this.options.model.toJSON() ))    
    return this

friend.jst.ejs:

<td><a href="/bgjavascript:void(0);" data-friendid="<%= id %>" class="friend-link"><%= name %></a></td>
<td><span class="label"><%= status %></span></td>

index.jst.ejs:

<table id="friends_table" class="table table-striped table-bordered">
    <tr>
      <td>Name</td>
      <td>Status</td>
    </tr>
</table>

Първоначално инстанцирам и попълвам колекцията, използвайки нулиране, както следва:

friends = new Tracker.Collections.FriendsCollection()
friends.reset data

След това създавам своя индексен изглед и му предавам моята колекция:

view = new Tracker.Views.Friends.IndexView(friends: friends)

Всичко това работи добре и се показва таблица с редове от уеб сървъра. След това обаче искам периодично да актуализирам списъка с приятели с промени, които са се случили на сървъра, така че използвам метода collection.fetch, както следва (където updateStatus е нещо напълно несвързано с описания досега код):

window.setInterval (->
  friends.fetch success: updateStatus
), 10000

Данните се връщат от извличане и се анализират правилно, но добавят редове към моята таблица, вместо да актуализират съществуващите редове. Как мога да накарам това да работи по начина, по който възнамерявам?


person sethdeckard    schedule 27.04.2012    source източник


Отговори (1)


Всъщност никога не изчиствате масата, когато тя бъде нулирана.

Актуализирайте своята addAll функция, за да изчистите таблицата. Нещо като това:

class Tracker.Views.Friends.IndexView extends Backbone.View
  template: JST["backbone/templates/friends/index"]

  # ...

  addAll: () ->
    @$("tbody").empty()
    @options.friends.each(this.addOne)

  # ...

Имайте предвид, че изчистването по този начин може да е малко пропускливо в зависимост от това колко сложен е вашият код/взаимодействия. Може да се наложи да запазите препратка към всеки дъщерен изглед, когато се добавят, след което при изчистване преминавате през всеки и извиквате какъвто и да е вашият персонализиран код за премахване (ако имате такъв).

Може също да се наложи да обвиете заглавката на таблицата във вашия файл index.jst.ejs, така че да не се изчиства с останалата част от тялото на таблицата:

<table id="friends_table" class="table table-striped table-bordered">
    <thead>
        <tr>
          <td>Name</td>
          <td>Status</td>
        </tr>
    </thead>
</table>
person Kevin Peel    schedule 27.04.2012
comment
Първата част работи, благодаря, но ако добавя маркера thead, никога не се добавят редове и остава само празна таблица със заглавки. - person sethdeckard; 27.04.2012
comment
Трябваше също да декларирам празен етикет tbody. - person sethdeckard; 27.04.2012
comment
А, забравих да добавя това там. Добро хващане. - person Kevin Peel; 29.04.2012