Коллекции в магистральных js не позволяют вам атрибуты set
, но я часто обнаруживаю, что необходимо хранить некоторую метаинформацию о коллекции. Где лучше всего установить эту информацию?
Установка атрибутов в коллекции - магистраль js
Ответ 1
Вероятно, лучше всего использовать коллекцию именно так, как она была предназначена: как набор моделей. (Жюльен уже прокомментировал это на OP, я хотел бы дать объяснение, почему я думаю, что он прав)
Предположим, вы думаете о библиотеке (коллекции) книги (модели), как в примерах документации Backbone. Имеет смысл, что у вас есть метаинформация о библиотеке, которую вы хотите сохранить, например адрес, в котором находится эта библиотека книг.
Трюк - это не думать о нем как метаинформации. У вас есть библиотека с множеством свойств, и одним из этих свойств является ее коллекция книг.
var Book = Backbone.Model.extend({
title: "Moby Dick"
});
var Collection = Backbone.Collection.extend({
model: Book
});
var Library = {
address: '45th Street',
collection: Collection
};
В этом примере я определил библиотеку как обычный объект JavaScript. Очевидно, вы также можете сделать библиотеку моделью, чтобы она имела все колокольчики и свистки. Я хочу сказать, что вам нужно представить реальность более реалистично, сделав один шаг назад и увидев, что дополнительные свойства, которые вы хотите назначить для коллекции, на самом деле являются родственными свойствами объекта на один уровень: библиотека в этом случае.
Ответ 2
Просто .extend
коллекция с функцией хранения метаданных.
var MyCollection = Backbone.Collection.extend({
initialize: function() {
...
this._meta = {};
},
model: ...
meta: function(prop, value) {
if (value === undefined) {
return this._meta[prop]
} else {
this._meta[prop] = value;
}
},
});
var collection = new MyCollection();
collection.add(someModels);
collection.meta("someProperty", value);
...
var value = collection.meta("someProperty");
Там могут быть лучшие места для хранения определенных метаданных, но это полностью зависит от метаданных.
Для хранения общих метаданных, расширяющих ваш конструктор коллекции, с помощью метода, с которым нужно работать, должно работать.
Будьте осторожны, если эти метаданные должны быть сохранены и загружены с сервера, тогда у вас есть большая задача.
Ответ 3
Я обновил подход Raynos с запуском событий, поэтому мы можем привязываться к обновлению атрибутов коллекции.
cls.groups = Backbone.Collection.extend({
// ...
// Reference to this collection model.
model: cls.group,
initialize: function() {
this._attributes = {}
},
// Extend collection with ability to store attributes and trigger events on attributes changing
attr: function(prop, value) {
if (value === undefined) {
return this._attributes[prop]
} else {
this._attributes[prop] = value;
this.trigger('change:' + prop, value);
}
},
// ...
});
cls.group = Backbone.View.extend({
// ...
initialize: function() {
// Catching attribute update
app.groups.on('change:selected', function(value) {
// ...
}, this);
},
// ...
events: {
'click' : function(e) {
// Set collection meta attribute on model view click event
app.groups.attr('selected', this.model.cid);
}
}
// ...
});
Ответ 4
Использование функции meta
решения @Raynos с одним параметром для меня не сработало. Поэтому я использовал следующий код:
var MyCollection = Backbone.Collection.extend({
initialize: function() {
this._meta = {};
},
put: function(prop, value) {
this._meta[prop] = value;
},
get: function(prop) {
return this._meta[prop];
}
});
var collection = new MyCollection();
collection.put("someProperty", 12);
alert(collection.get("someProperty"));
Надеюсь, это поможет.