Магистрально-реляционный 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 3

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');

Http://jsfiddle.net/theotheo/5DAzx/

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

Весь следующий код находится в представлении карты (где отображаются заметки).

Сначала я привязываю метод 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 вытащит лениво загруженные записи-это на самом деле не так.

В качестве побочного замечания, этот взгляд на самом деле является модальным и должен быть открыт и закрыто (удалено со страницы). Чтобы предотвратить проблему зомби-событий, описанную в этом превосходном посте, я также вручную разматываю события, упомянутые выше.