2012-04-25 4 views
7

Lors de l'utilisation de backbone.js et du moteur de modèle de compagnon en trait de soulignement, j'ai remarqué que la plupart des exemples appelaient model.ToJSON() lors du rendu au lieu de passer simplement model. Je comprends que mon modèle devrait modifier la façon dont il récupère les données.Backbone/Underscore Template - lors du rendu, pourquoi appeler jSON?

Je me demande pourquoi & quel est le bénéfice de toJSON()?

Exemple typique

Dans l'exemple typique model.toJSON() est appelée lors du rendu. Notez, par souci de brièveté, je mets le modèle dans un littéral de chaîne.

ToDoItemView = Backbone.View.extend({ 
    /* other viewey stuff */ 
    template : _.template('<li><%=ToDoNote%></li>'), 
    render : function() {  
        var out= this.template(this.model.toJSON()); //<--JSON 
        $(this.el).html(out) } 
        return this; 
       } 
}); //end view 

Une Autre méthode

Je creusé dans la colonne vertébrale 0.9.2 & Code Souligner 1.3.3. Dans l'épine dorsale, a remarqué que model.toJSON() fait ce qui suit: _.clone(this.attributes). À l'intérieur du moteur de rendu du modèle, mon modèle compilé nomme les données transmises obj. Après avoir vu ces extraits, j'ai réalisé que le clonage des attributs n'est pas nécessaire. Au lieu de cela, je peux passer directement dans mon modèle (mais avec quelques changements de syntaxe dans le modèle). Quelque chose comme ...

ToDoItemView = Backbone.View.extend({ 
    /* other viewey stuff */ 
    template : _.template('<li><%=obj.get('ToDoNote')%></li>'), //<--notice GET() 
    render : function() {  
        var out= this.template(this.model); //<-- look ma no json 
        $(this.el).html(result) } 
        return this; 
       } 
}); //end view 

En regardant les deux exemples, les seules raisons pour lesquelles je peux trouver pour appeler toJSON sont:

  • protéger les données du modèle d'une vue infâmes
  • la vue locale modifie les données (pas une bonne idée à mon avis),
  • vue a besoin d'accéder à l'aide des valeurs tableau/syntaxe de chaîne (obj[ namepart + someindex])

Ma question se résume à: pourquoi devrais-je appeler toJSON() et prendre le coup pour cloner les propriétés, plutôt que d'utiliser simplement get() dans mes modèles?

+0

« le coup pour le clonage »? Vous pensez que l'appel 'get' est gratuit? –

+0

@muistooshort - Gratuit? non. 'Get()' ne renvoie pas this.attributes [attr]; '. Ainsi, une recherche de tableau est-elle plus rapide qu'un clone de tableau? Oui - du point de vue des ressources et du temps, mais cela me manque. Appeler 'toJSON()' est clairement intégré dans la pensée collective des communautés de base. Je suis curieux de savoir pourquoi. – EBarr

+0

"Appels de fonction répétés et accès aux objets" par opposition à "un clone et accès répétés aux objets" et je ne vois aucun résultat de référence donc votre * Oui * est simplement opinion (comme toutes les réponses vont être, d'où le "non "vote constructif"). Toutes les vues ne seront pas une cartographie directe d'un modèle ou d'une collection, toJSON est plus flexible et réduit le bruit dans votre modèle. –

Répondre

12

Peut-être que ce qui suit est logique:

  1. INTERPOLATION au lieu d'évaluer est un grand coût à prendre. Donc, votre version du modèle est en fait beaucoup plus lent que d'appeler toJSon() et en utilisant l'évaluation.

  2. La logique appartient aux vues et non aux modèles. Introduire le code js (et le besoin d'interpolation) dans les templates ne devrait être fait que si nécessaire.

  3. On pourrait argumenter que vous devriez passer model.attributes au lieu de model.toJSON() en évitant le clone. Je suppose que la raison de ne pas le faire est d'éviter de laisser le modèle changer les attributs du modèle.De plus, vous pouvez généralement vouloir augmenter le résultat de model.toJSON() avec d'autres choses, ce qui est évident que vous ne voulez pas faire sur le model.attributes

+0

Bien dit. Fait beaucoup de sens. – EBarr

+2

Il est à noter que l'utilisation de 'model.toJSON()' est déconseillée pour les vues ... c'est pour la sérialisation du modèle pour la synchronisation, pas pour le rendu. Vous devriez passer 'model.attributes' comme vous l'avez suggéré. https://github.com/jashkenas/backbone/issues/2134 – Cobby

+0

Même l'utilisation de 'toJSON()' ou de '_.clone()' n'empêche peut-être pas totalement le modèle de modifier les attributs du modèle car la méthode clone crée "un peu profond". clone copié de l'objet: tous les objets ou tableaux imbriqués seront copiés par référence et non dupliqués. " (http://underscorejs.org/#clone) Donc, je recommande d'utiliser 'model.attributes', mais attention à ne pas modifier le modèle du template dans tous les cas. – gfullam

2

Une raison probable est que les développeurs de Backbone.js vous ont permis d'utiliser n'importe quel moteur de template que vous désirez, et de nombreux moteurs de templates fonctionnent avec de simples objets javascript, pas Backbone Models.

+1

Bon point. Bien que, je parle spécifiquement pourquoi/pourquoi-ne pas choisir cette stratégie * pour un modèle de soulignement *. – EBarr

Questions connexes