Получить / collection / id в магистрали без загрузки всей коллекции

#collections #model #backbone.js

#Коллекции #Модель #backbone.js

Вопрос:

Есть ли способ загрузить отдельный объект магистральной коллекции (с сервера)?

 Backbone.Collection.extend({
  url: '/rest/product'
});
  

Следующий код может загрузить всю коллекцию с помощью collection.fetch() , но как загрузить одну модель? В документации Backbone четко сказано, что GET можно сделать /collection[/id] , но не как.

Ответ №1:

Модель должна быть объявлена таким образом:

 Backbone.Model.extend({
  url: function() {
    return '/rest/product/' this.id;
  }
});
  

Использовать ее просто, поскольку:

 var model = new ProductModel();
model.id = productId;
model.fetch({ success: function(data) { alert(JSON.stringify(data))}});
  

Комментарии:

1. Вы уверены, что можно использовать model.id = productId вместо model.set('id', productId) ?

2. Да, конечно. Модель использует this.id который не является атрибутами магистрали. Использование model.set(‘id’, ..) требует использования model.get(‘id’) в соответствующем классе. Оба варианта работают, мой не будет влиять на атрибуты модели магистрали: D

Ответ №2:

Пока мы устанавливаем

 url:"api/user" 
  

для коллекции эквивалентом для модели является

 urlRoot:"api/user"
  

это заставит backbone автоматически добавлять /id при извлечении()

Ответ №3:

collection.fetch( {data: { id:56 } } )

Комментарии:

1. Работает, как ожидалось 1. Но это выдает мне ошибку после выполнения приведенной выше строки. Uncaught TypeError: object is not a function . Вы можете помочь?

Ответ №4:

Я сделал это:

 Catalog.Categories.Collection = Backbone.Collection.extend({
fetchOne : function (id, success) {
    var result = this.get(id);
    if (typeof result !== 'undefined') {
        console.log(result, 'result')
        success.apply(result);
        return;
    }
    var where = {};
    where[this.model.prototype.idAttribute] = id;
    var model = new this.model(where);
    this.add(model);
    console.log(this._idAttr, where, this.model)
    model.fetch({success: function () {
        success.apply(model);
    }});
}
};
  

Теперь вызовите это:

 collection.fetchOne(id, function () {console.log(this)});
  

Больше не нужно гадать, есть ли модель уже в коллекции!. Однако вам придется использовать обратный вызов, поскольку вы не можете зависеть от результата запугивания. Вы могли бы использовать async false, чтобы обойти это ограничение.

Комментарии:

1. Это работает лучше и может быть легко добавлено в прототип коллекции Backbone

Ответ №5:

просто .fetch Модель.

Итак, создайте модель с ее собственной .url функцией.

Что-то вроде

 function url() {
  return "/test/product/"   this.id;
}
  

Комментарии:

1. Следующий код не работает: url: '/rest/product/' this.id

2. @yvesamsellem после более внимательного прочтения, .url должна быть функция

3. @Raynos спасибо. Есть ли способ не повторять URL-адрес в модели и коллекции?

4. @yvesamsellem Единственный способ, который я могу придумать, — это расширить коллекцию. С функцией отложенной загрузки

5. @Raynos не могли бы вы, пожалуйста, дополнить свой ответ примером кода?

Ответ №6:

Я сделал это:

 var Product = Backbone.Model.extend({});
var Products = Backbone.Collection.extend({
  model: Product,
  url: '/rest/product'
});
var products = new Products();
var first = new Product({id:1});
first.collection = products;
first.fetch();
  

Преимущество этого заключается в том, что оно работает, когда вы не используете механизм хранения REST (вместо этого используя что-то вроде локального хранилища HTML5 или так далее)