Les collections dans la colonne vertébrale js ne vous permettent pas d'attribuer set
attributs, mais je trouve souvent qu'il est nécessaire de stocker des méta-informations sur une collection. Où est le meilleur endroit pour définir cette information?
Réponses
Trop de publicités?Juste .extend
la collection avec un méta-données de la fonction de stockage.
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");
Il peut y avoir de meilleurs endroits pour stocker spécifiques méta-données, mais cela dépend entièrement de ce que les méta-données.
Pour le stockage des méta données de l'extension de votre collection de constructeur avec une méthode pour faire face à cela devrait fonctionner.
Méfiez-vous que si cette méta-données doivent être enregistrées et chargées à partir du serveur, puis vous avez une plus grande tâche à portée de main.
Il est probablement préférable d'utiliser de la Collection dans eactly la façon dont il a été prévu: comme un ensemble de modèles. (Julien déjà commenté ce sur l'OP, je voudrais donner une explication des raisons pour lesquelles je pense qu'il est à droite)
Disons que vous êtes à réfléchir à une Bibliothèque (collection) de Livre (modèle), comme dans l'épine Dorsale de la documentation des exemples. Il est logique que vous avez des méta-informations sur la bibliothèque où vous souhaitez stocker, comme l'adresse où ce livre de la bibliothèque est située.
L'astuce est de ne pas penser comme des méta-informations. Vous avez une bibliothèque qui a beaucoup de propriétés, et l'une de ces propriétés est la collection de livres.
var Book = Backbone.Model.extend{ title: "Moby Dick" }
var Collection = Backbone.Collection.extend({
model: Book
})
var Library = {
address: "45th Street",
collection: Collection
}
Dans cet exemple, j'ai défini la Bibliothèque comme un simple objet javascript. Évidemment, vous pouvez aussi faire de la Bibliothèque un modèle, de sorte qu'il a tout l'épine Dorsale de cloches et de sifflets. Mon point ici est que vous avez besoin de représenter la réalité de manière plus réaliste en prenant un pas en arrière et de voir que les propriétés supplémentaires que vous souhaitez attribuer à la Collection sont en fait frère propriétés d'un objet d'un niveau: la Bibliothèque dans ce cas.
J'ai amélioré l'approche de Raynos avec le déclenchement d'événements afin que nous puissions nous lier à la mise à jour des attributs de la collection.
cls.groups = Backbone.Collection.extend({
// ...
// Reference to this collection's 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's view click event
app.groups.attr('selected', this.model.cid);
}
}
// ...
});
L'utilisation de la fonction meta
de la solution @Raynos avec un seul paramètre ne fonctionne pas pour moi. J'ai donc utilisé le code suivant:
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"));
J'espère que ça va aider.