Магистрально-реляционный fetchRelated не отправляющий запрос
Я использую позвоночник.js и backbone relational 0.5.0 с бэкэндом Rails 3.2. У меня есть модель карты, которая имеет множество заметок.
Вот мои модели и коллекции JS:
Workflow.Collections.Cards = Backbone.Collection.extend({
model: Workflow.Models.Card,
url: '/cards'
});
Workflow.Models.Card = Backbone.RelationalModel.extend({
modelName : 'card',
urlRoot : '/cards',
relations: [
{
type: Backbone.HasMany,
key: 'notes',
relatedModel: 'Workflow.Models.Note',
collectionType: 'Workflow.Collections.Notes',
includeInJSON: false,
reverseRelation: {
key: 'card',
includeInJSON: 'id'
}
}]
});
Workflow.Collections.Notes = Backbone.Collection.extend({
model: Workflow.Models.Note,
url: '/cards/74/notes' // intentionally hard-coded for now
});
Workflow.Models.Note = Backbone.RelationalModel.extend({
modelName : 'note',
urlRoot : '/notes'
});
Нормальная выборка работает отлично, но когда я пытаюсь fetchRelated в консоли, я получаю пустой массив:
card = new Workflow.Models.Card({id: 74}) // cool
card.fetch() // hits the sever with GET "/cards/74" - works great
card.fetchRelated('notes') // [] - didn't even try to hit the server
Странно то, что это работает:
card.get('notes').fetch() // cool - GET "/cards/74/notes"
Я мог бы использовать этот метод и анализировать текст ответа, но он кажется очень грязным.
Кто-нибудь знает, чего мне не хватает здесь?
Заранее спасибо, этот действительно мучает меня!
Стю
2 ответа:
Вы должны создать
Card
с массивом идентификаторовNote
:card = new Workflow.Models.Card({id: 74, notes: [74, 75]});
и соответственно изменить методurl
Notes
:Workflow.Collections.Notes = Backbone.Collection.extend({ model: Workflow.Models.Note }); Workflow.Models.Note = Backbone.RelationalModel.extend({ modelName : 'note', urlRoot : function () { return this.get('card').url() + '/notes'; } }); card = new Workflow.Models.Card({id: 74, notes: [74, 75]}); card.fetchRelated('notes');
Я должен был опубликовать свое решение некоторое время назад - вполне возможно, что есть лучший способ, но это соглашение, с которым я пошел:
Весь следующий код находится в представлении карты (где отображаются заметки).
Сначала я привязываю метод
renderNotes
к событию'reset'
в коллекции заметок карты:initialize: function () { _.bindAll(this); this.model.get('notes').on('reset', this.renderNotes); var self = this; this.model.get('notes').on('add', function(addedNote, relatedCollection) { self.renderNote(addedNote); }); }
Я также связываю с
'add'
на этой коллекции, чтобы вызвать сингулярноеrenderNote
.Методы renderNotes и renderNote работают следующим образом это:
renderNotes: function () { if (this.model.get('notes')) { this.model.get('notes').each(this.renderNote); } }, renderNote: function (note) { var noteView = new Workflow.Views.Note({ model: note }); this.$('.notes').append(noteView.render().el); },
Затем, последний кусочек головоломки должен фактически ударить по серверу для заметок карты (что, в свою очередь, вызовет событие
'reset'
, которое я связал выше). Я делаю это в методеrender
вида карты:render: function () { // render all of the eager-loaded things this.model.get('notes').fetch(); return this; },
Как @ user1248256 любезно помог мне разобраться в комментариях к моей ОП, путаница заключалась главным образом в том, что я ожидал, что
fetchRelated
вытащит лениво загруженные записи-это на самом деле не так.В качестве побочного замечания, этот взгляд на самом деле является модальным и должен быть открыт и закрыто (удалено со страницы). Чтобы предотвратить проблему зомби-событий, описанную в этом превосходном посте, я также вручную разматываю события, упомянутые выше.