Question de base pour les débutants:

Contexte: création d'une liste de courses avec colonne vertébrale

J'ai une classe de modèle appelée avec les propriétés name, description et tags (array). Je voudrais créer deux vues basées sur ce modèle ou la collection de ce modèle.

La première vue affichera tous les éléments comme celui-ci:

<ul>
<li><h3>Item 1 Name</h3>
<p>Item 1 Description</p>
<p>Tag1, Tag2 ,Tag3</p>
</li>
.......
</ul>

La deuxième vue affichera une liste de balises et le nombre d'éléments balisés comme ceci:

<ul>
<li>Tag1<span>{count of items tagged with tag1}</span></li>
<li>Tag2<span>{count of items tagged with tag2}</span></li>
<li>Tag3<span>{count of items tagged with tag3}</span></li>
</ul>

J'ai construit le modèle, la collection et la vue pour prendre en charge la première vue. Je voudrais savoir comment utiliser le modèle existant (ou créer un nouveau modèle?) Pour créer la deuxième vue.

Merci d'avance...

Modèle et collection d'articles existants (extraits de l'exemple Todo.js)

window.Item = Backbone.Model.extend({
// Default attributes for a todo item.
defaults: function() {
return {
order: Items.nextOrder()
};
}
});


window.ItemList = Backbone.Collection.extend({

model: Item,

localStorage: new Store("items"),

nextOrder: function() {
  if (!this.length) return 1;
  return this.last().get('order') + 1;
},

comparator: function(item) {
  return item.get('order');
}

});

MISE À JOUR: Même si la substitution de la méthode parse () fonctionne lors de l'affichage des noms de balises avec le nombre d'éléments, je n'ai pas pu actualiser la liste des noms de balises / nombre d'éléments après avoir ajouté un nouvel élément. Cela peut être dû au fait que les vues sont rendues à partir de différentes collections. J'essaierai d'étendre la collection ItemList et de remplacer la méthode parse (). Toute aide est grandement appréciée.

11
Alper 22 déc. 2011 à 03:29

4 réponses

Meilleure réponse

Paul Yoder du groupe Google Backbone.js a fourni la solution. Vous pouvez le consulter ici

3
Alper 5 janv. 2012 à 14:58

@machineghost a raison; Les modèles sont totalement découplés des vues afin que vous puissiez faire autant de vues attachées au même modèle que vous le souhaitez. Vous pouvez également étendre une vue s'ils ont une logique ou des attributs que vous souhaitez partager. Lorsque j'utilise Backbone, je me retrouve souvent à étendre une vue parent juste pour remplacer la fonction render ou pour fournir un modèle différent.

Première vue

ShoppingCartView = Backbone.View.extend({
  model: ShoppingCart
  ...
});

Deuxième vue indépendante

CheckoutView = Backbone.View.extend({
  model: ShoppingCart
  ...
});

La deuxième vue s'étend en premier

CheckoutView = ShoppingCartView.extend({ 
  template: a_different_template // syntax depends on your templating framework
  ... 
});
12
goggin13 22 déc. 2011 à 01:29

Je suis moi-même assez nouveau sur Backbone.js, alors prenez cette réponse avec un grain de sel, mais je pense ... vous venez de faire la deuxième vue. L'intérêt du découplage des modèles et des vues est de faire en sorte que vous n'ayez rien à faire avec les modèles si tout ce que vous voulez faire est de faire quelque chose de différent avec vos vues.

Donc, je pense qu'il vous suffit de créer YourView2, de lui dire d'utiliser le même modèle que YourView1 et vous devriez être en affaires.

3
machineghost 22 déc. 2011 à 01:02

Après quelques recherches, j'ai trouvé la méthode Collection.Parse. cela semble être le bon endroit pour transformer la réponse après une opération fetch (). On dirait que j'aurai besoin d'un nouveau modèle d'ensemble, d'une collection et d'objets de vue. C'est ainsi que j'ai implémenté la fonction d'analyse dans mon objet de collection. Testé avec succès dans Chrome. N'hésitez pas à suggérer des améliorations

    <snip>
    parse: function(response) {

        var items = response; //the raw item model returned from localStorage  
        var tagNameItemCount = [];
        var selectedTags = ["Tag1", "Tag2", "Tag3"];
        for(i = 0; i < selectedTags.length; i++){
            var currentTagName = selectedTags[i];
            var currentItemCount = this.getItemsCountByTagName(currentTagName, items);
            tagNameItemCount.push({tagName: currentTagName, tagCount: currentItemCount});
        }

        return tagNameItemCount;



       },
getItemsCountByTagName: function (tagName, items) {
                        var taggedItems = _.filter(items, function(item){ return _.include(item.tags, tagName); });
                        return taggedItems.length;
                       },

     </snip>
0
Alper 22 déc. 2011 à 16:33