Backbone: Los atributos de vista personalizados se comparten entre diferentes instancias

Creado en 19 abr. 2012  ·  9Comentarios  ·  Fuente: jashkenas/backbone

Vea este violín: http://jsfiddle.net/XgPyH/31/

Así que estamos creando 10 instancias de itemView y llamando al método addItem para agregar 10 elementos a cada itemView. Cada itemView debe tener 10 elementos en su propiedad itemArray. Pero, en cambio, comparten la propiedad itemArray y tienen 100 elementos en ella.

El problema podría ser que backbone.view no restablece los atributos personalizados en el constructor.

question

Comentario más útil

Sí, dado que itemArray es una propiedad del prototipo itemView , todas las instancias de itemView lo comparten. Si desea que las instancias tengan su propio itemArray , debe configurarlo en initialize o en el constructor.

var ItemView = Backbone.View.extend({

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

  ...

});

Todos 9 comentarios

Sí, dado que itemArray es una propiedad del prototipo itemView , todas las instancias de itemView lo comparten. Si desea que las instancias tengan su propio itemArray , debe configurarlo en initialize o en el constructor.

var ItemView = Backbone.View.extend({

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

  ...

});

Aquí hay un violín que hace lo que describiste: http://jsfiddle.net/XgPyH/32/

Hola @braddunbar ,

Ya usamos la misma solución que publicaste como solución alternativa, pero parece que no deberíamos necesitar hacer eso. Es un comportamiento bastante confuso, ¿no crees?

¿Puede explicar qué uso tiene tener eso en el prototipo (no lo entiendo del todo, no estoy diciendo que la implementación actual sea incorrecta, solo estoy tratando de obtener una aclaración para que podamos entender)?

A menudo especificamos todas las propiedades de nuestra vista en la forma en que @spawnedc usó en su violín, ya que entonces está claro cuáles son las propiedades de la vista, si luego tenemos que "anularlas" en el método de inicialización, eso simplemente parece engorroso .

En las aplicaciones de ejemplo, las propiedades de las vistas se especifican exactamente de la misma manera (consulte Todo.js). una variable de "plantilla" se especifica de la misma manera, pero, por supuesto, debido a que es una cadena que no cambia, nunca vemos este tipo de problema.

¿Cuál es la forma correcta de especificar las propiedades de la vista dinámica, seguramente no es el caso que tengamos que anularlas todas en el método init ...?

¿Puedes explicar qué utilidad tiene tener eso en el prototipo?

Poner propiedades mutables (matrices, hashes, etc.) en el prototipo rara vez es útil en mi experiencia (aunque estoy seguro de que hay algunos casos en los que lo es).

¿Cuál es la forma correcta de especificar las propiedades de la vista dinámica, seguramente no es el caso que tengamos que anularlas todas en el método init ...?

Sí, para establecer una propiedad con un valor mutable en cada instancia de una clase / constructor, debe hacerlo en el constructor (o en este caso initialize , que se llama desde el constructor).

Por ejemplo, así es como Backbone configura las propiedades en una instancia de Backbone.Model .

@braddunbar Si creo una instancia _new_ , esperaría que _todas_ las propiedades se restablezcan, ya que es una instancia _brand new_ . ¿No es este el comportamiento esperado o me falta algo?

Hola @braddunbar ,

Poner propiedades mutables (matrices, hashes, etc.) en el prototipo rara vez es útil en mi experiencia (aunque estoy seguro de que hay algunos casos en los que lo es).

¿No es eso exactamente lo que Bacbone está haciendo con itemArray en este caso? itemArray está en el prototipo, ¿por eso ocurre el comportamiento que estamos experimentando?

Estoy 100% de acuerdo con la última declaración de @spawnedc . No esperaría que ninguna propiedad se compartiera entre instancias de vistas de "hermanos".

En realidad, ninguna de las propiedades se restablece a menos que se restablezcan en el constructor. Son siempre las mismas propiedades de prototipo compartidas por todas las instancias creadas por el mismo constructor.

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 está interesado hay una gran explicación aquí .

¿No es eso exactamente lo que Bacbone está haciendo con itemArray en este caso? itemArray está en el prototipo, ¿por eso ocurre el comportamiento que estamos experimentando?

Exactamente. Por eso recomiendo crear itemArray en initialize lugar de como una propiedad prototipo.

@braddunbar Gracias por la explicación y el enlace. Sigue siendo un comportamiento extraño (e inesperado) por un lado, pero por otro lado tiene mucho sentido compartir las propiedades entre vistas.

Leeré el artículo de JavaScript Garden y estoy seguro de que todo quedará claro :).

¿Fue útil esta página
0 / 5 - 0 calificaciones