#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 или так далее)