Backbone: Les attributs de vue personnalisés sont partagés entre différentes instances

Créé le 19 avr. 2012  ·  9Commentaires  ·  Source: jashkenas/backbone

Veuillez voir ce violon: http://jsfiddle.net/XgPyH/31/

Nous créons donc 10 instances de itemView et appelons la méthode addItem pour ajouter 10 éléments à chaque itemView. Chaque itemView doit avoir 10 éléments dans leur propriété itemArray. Mais à la place, ils partagent la propriété itemArray et contiennent 100 éléments.

Le problème peut être que backbone.view ne réinitialise pas les attributs personnalisés dans le constructeur.

question

Commentaire le plus utile

Oui, puisque itemArray est une propriété du prototype itemView , il est partagé par toutes les instances de itemView . Si vous voulez que les instances aient leur propre itemArray vous devez le définir dans initialize ou dans le constructeur.

var ItemView = Backbone.View.extend({

  initialize: function() {
    this.itemArray = [];
  },

  ...

});

Tous les 9 commentaires

Oui, puisque itemArray est une propriété du prototype itemView , il est partagé par toutes les instances de itemView . Si vous voulez que les instances aient leur propre itemArray vous devez le définir dans initialize ou dans le constructeur.

var ItemView = Backbone.View.extend({

  initialize: function() {
    this.itemArray = [];
  },

  ...

});

Voici un violon qui fait ce que vous avez décrit: http://jsfiddle.net/XgPyH/32/

Salut @braddunbar ,

Nous avons déjà utilisé la même solution que vous avez publiée comme solution de contournement, mais il semble que nous ne devrions pas avoir besoin de le faire. C'est un comportement assez déroutant, n'est-ce pas?

Pouvez-vous expliquer l'utilité d'avoir cela sur le prototype (je ne comprends pas très bien, je ne dis pas que l'implémentation actuelle est incorrecte - essayez simplement d'obtenir des éclaircissements pour que nous puissions comprendre).

Nous spécifions souvent toutes les propriétés de notre vue de la même manière que

Dans les exemples d'applications, les propriétés des vues sont spécifiées exactement de la même manière (voir Todo.js). une variable "template" est spécifiée de la même manière, mais bien sûr, parce que c'est juste une chaîne immuable, nous ne voyons jamais ce genre de problème.

Quelle est la bonne façon de spécifier les propriétés de la vue dynamique, ce n'est sûrement pas le cas que nous devions toutes les remplacer dans la méthode init ...?

Pouvez-vous expliquer l'utilité d'avoir cela sur le prototype

Mettre des propriétés mutables (tableaux, hachages, etc.) sur le prototype est rarement utile dans mon expérience (même si je suis sûr qu'il y a des cas dans lesquels c'est le cas).

Quelle est la bonne façon de spécifier les propriétés de la vue dynamique, ce n'est sûrement pas le cas que nous devions toutes les remplacer dans la méthode init ...?

Oui, pour définir une propriété avec une valeur mutable sur chaque instance d'une classe / constructeur, vous devez le faire dans le constructeur (ou dans ce cas initialize , qui est appelé depuis le constructeur).

À titre d'exemple, voici comment Backbone configure les propriétés dans une instance de Backbone.Model .

@braddunbar Si je crée une _new_ instance, je m'attendrais à ce que _all_ les propriétés soient réinitialisées car il s'agit d'une instance _brand new_ . N'est-ce pas le comportement attendu ou est-ce que je manque quelque chose?

Salut @braddunbar ,

Mettre des propriétés mutables (tableaux, hachages, etc.) sur le prototype est rarement utile dans mon expérience (même si je suis sûr qu'il y a des cas dans lesquels c'est le cas).

N'est-ce pas exactement ce que Bacbone fait avec itemArray dans ce cas? itemArray est sur le prototype, c'est pourquoi le comportement que nous expérimentons se produit?

Je suis à 100% d'accord avec la dernière déclaration de @spawnedc . Je ne m'attendrais pas à ce que des propriétés soient partagées entre des instances de vues "frères".

En fait, aucune des propriétés n'est réinitialisée sauf si elles sont réinitialisées dans le constructeur. Ce sont toujours les mêmes propriétés de prototype partagées par toutes les instances créées par le même constructeur.

var A = function(){};
var a = new A();

var B = function(){};
B.prototype = a;
a.constructor = B;

var b1 = new B();
var b2 = new B();

console.log(b1.foo); // undefined
console.log(b2.foo); // undefined

a.foo = [1];

console.log(b1.foo); // [1]
console.log(b2.foo); // [1]

console.log(b1.foo === b2.foo); // true

Si vous êtes intéressé, il y a une excellente explication ici .

N'est-ce pas exactement ce que Bacbone fait avec itemArray dans ce cas? itemArray est sur le prototype, c'est pourquoi le comportement que nous expérimentons se produit?

Exactement. C'est pourquoi je recommande de créer itemArray dans initialize plutôt qu'en tant que propriété prototype.

@braddunbar Merci pour l'explication et le lien - C'est toujours un comportement étrange (et inattendu) d'une part, mais d'autre part, il est tout à fait logique de partager les propriétés entre les vues.

J'aurai une lecture de l'article JavaScript Garden et je suis sûr que tout deviendra clair :).

Cette page vous a été utile?
0 / 5 - 0 notes