2013-12-04 2 views
1

Мне интересно, есть ли указатели на лучший способ «выборки», а затем привязка коллекции данных к представлению в Backbone.js.Правильный способ привязки результатов операции getbone.js async fetch к представлению

Я заполняю свою коллекцию с помощью операции извлечения асинхронных объектов и при успешной привязке результатов к шаблону для отображения на странице. Поскольку операция выборки async выполняется из основного потока, я теряю ссылку на объект представления магистрали (SectionsView в этом случае). Поскольку это так, я не могу ссылаться на $ el, чтобы добавить результаты. Я вынужден создать еще одну ссылку DOM на странице для ввода результатов. Это работает, но я не доволен тем, что

Я потерял ссылку на мой взгляд, когда выполняется асинхронная выборка, есть ли более чистый способ реализации этого? Я чувствую, что мне что-то не хватает ... Любые указатели будут оценены.

SectionItem = Backbone.Model.extend({ Title: '' }); 
SectionList = Backbone.Collection.extend({ 
    model: SectionItem, 
    url: 'http://xxx/api/Sections', 
    parse: function (response) { 
     _(response).each(function (dataItem) { 
      var section = new SectionItem(); 
      section.set('Title', dataItem); 
      this.push(section); 
     }, this); 

     return this.models; 
    } 
}); 

//Views--- 
var SectionsView = Backbone.View.extend(
     { 
      tagName : 'ul', 
      initialize: function() { 
       _.bindAll(this, 'fetchSuccess'); 
      }, 
      template: _.template($('#sections-template').html()), 
      render: function() { 
       var sections = new SectionList(); 
       sections.fetch({ success: function() { this.SectionsView.prototype.fetchSuccess(sections); } }); //<----NOT SURE IF THIS IS THE BEST WAY OF CALLING fetchSuccess? 
       return this; 
      }, 
      fetchSuccess: function (sections) { 
       console.log('sections ' + JSON.stringify(sections)); 
       var data = this.template({ 
        sections: sections.toJSON() 
       }); 
       console.log(this.$el); //<-- this returns undefined ??? 
       $('#section-links').append(data); //<--reference independent DOM div element to append results 
      } 
     } 
    ); 

ответ

1

darthal, почему вы повторно использовали синтаксический анализ? Кажется, что делает то, что делает Backbone по умолчанию (получите массив моделей из вызова AJAX и создайте модели + добавьте их в коллекцию).

Теперь на ваш вопрос ... вы должны использовать событие, чтобы выполнить рендеринг. У вас также есть добавить и удалить, когда отдельные экземпляры будут добавлены или удалены, но выбор приведет к сбросу коллекции (удалите все, а затем добавьте все) и вызовет только одно событие, сброс, не многие удаляют/добавляют.

Так что в вашем Initialize:

this.collection.on("reset", this.fetchSuccess, this); 

Если вы задаетесь вопросом, где this.collection исходит от, это парам вам нужно дать вашему виду, когда вы создаете, вы можете передавать или модель или коллекцию или и то, и другое, и они будут автоматически добавлены в контекст объекта (представления). Значение этого параметра должно быть экземпляром SectionList.

Вам также необходимо обновить fetchSuccess, чтобы полагаться на this.collection вместо некоторых параметров. Магистральные коллекции предоставляют метод .each, если вам нужно перебирать все модели, чтобы делать что-то вроде добавления HTML в DOM.

В большинстве случаев вам не нужен fetchSuccess, вы должны просто использовать рендер: когда сборник готов (при сбросе), визуализируйте DOM на основе коллекции.

Так суммировать наиболее общие закономерности:

  1. Коллекция должна быть независимой от точки зрения: вы даете коллекцию как пары к созданию представления, сбор не должен быть создан из конкретнога Посмотреть.

  2. Вы связать Вид на событие сброса коллекции (+ добавить, удалить, если вам нужно), чтобы запустить рендер()

    this.collection.on ("сброс", this.render, это);

  3. Вы делаете выборку в коллекции в любое время (возможно, при запуске приложения).

Типичный код для запуска приложения будет выглядеть примерно так:

var sections = new SectionList(); 
var sectionsView = new SectionsView({collection: sections}); 
sections.fetch(); 

Потому что вы связали событие сброса в исходное состояние с помощью зрения, вы не должны беспокоиться о чем-либо, функции представления render() будет запущен после извлечения.

+0

спасибо за подробный ввод Enders:) ... Я собираюсь пропустить ваш совет .... ответит более формально, как только у меня будет возможность просмотреть ваши шаги выше. – darthal

+0

hey Enders Спасибо ответ был действительно полезен, очень ценился. только одна модификация, хотя 'section.fetch ({reset: true});' см. ссылку здесь [ссылка] (http://stackoverflow.com/questions/15959306/backbone-js-fetch-method-does-not-fire- сброс-события). Чтобы ответить на ваш первый вопрос о синтаксическом анализе: сериализованный объект, возвращаемый с сервера, представляет собой простой список строк (например: '[" item1 "," item2 "," item3 "," item4 "," item5 "," item6 "] '), Я хотел отобразить их в определенное свойство на моей модели. это казалось самым чистым способом сделать это. – darthal

Смежные вопросы