Por favor, veja este violino: http://jsfiddle.net/XgPyH/31/
Portanto, estamos criando 10 instâncias de itemView e chamando o método addItem para adicionar 10 itens a cada itemView. Cada itemView deve ter 10 itens em sua propriedade itemArray. Mas, em vez disso, eles compartilham a propriedade itemArray e têm 100 itens nela.
O problema pode ser que o backbone.view não está redefinindo os atributos personalizados no construtor.
Sim, como itemArray
é uma propriedade do protótipo itemView
, ele é compartilhado por todas as instâncias de itemView
. Se você deseja que as instâncias tenham seus próprios itemArray
você deve defini-los em initialize
ou no construtor.
var ItemView = Backbone.View.extend({
initialize: function() {
this.itemArray = [];
},
...
});
Aqui está um violino que faz o que você descreveu: http://jsfiddle.net/XgPyH/32/
Olá @braddunbar ,
Já usamos a mesma solução que você postou como solução alternativa, mas parece que não deveríamos precisar fazer isso. É um comportamento bastante confuso, não acha?
Você pode explicar para que serve ter isso no protótipo (não entendo muito bem, não estou dizendo que a implementação atual está incorreta - apenas tentando obter alguns esclarecimentos para que possamos entender).
Freqüentemente especificamos todas as propriedades de nossa visão da maneira que @spawnedc usou em seu violino, já que fica claro quais são as propriedades da visão, se então tivermos que "sobrescrevê-las" no método de inicialização - bem, isso parece complicado .
Nos aplicativos de exemplo, as propriedades das visualizações são especificadas exatamente da mesma maneira (consulte Todo.js). uma variável "template" é especificada da mesma maneira, mas é claro, como é apenas uma string imutável, nunca vemos esse tipo de problema.
Qual é a maneira correta de especificar propriedades de visualização dinâmica, certamente não é o caso que temos que substituí-las todas no método init ...?
Você pode explicar para que serve ter isso no protótipo
Colocar propriedades mutáveis (matrizes, hashes, etc.) no protótipo raramente é útil em minha experiência (embora eu tenha certeza de que existem alguns casos em que é).
Qual é a maneira correta de especificar propriedades de visualização dinâmica, certamente não é o caso que temos que substituí-las todas no método init ...?
Sim, para definir uma propriedade com um valor mutável em cada instância de uma classe / construtor, você deve fazer isso no construtor (ou neste caso initialize
, que é chamado a partir do construtor).
Por exemplo, é assim que o Backbone configura propriedades em uma instância de Backbone.Model
.
@braddunbar Se eu criar uma instância _new_ , espero que _todas_ as propriedades sejam redefinidas, pois é uma instância de _brand new_ . Não é esse o comportamento esperado ou estou perdendo alguma coisa?
Olá @braddunbar ,
Colocar propriedades mutáveis (matrizes, hashes, etc.) no protótipo raramente é útil em minha experiência (embora eu tenha certeza de que existem alguns casos em que é).
Não é exatamente isso que Bacbone está fazendo com itemArray neste caso? itemArray está no protótipo, é por isso que o comportamento que estamos experimentando está acontecendo?
Eu concordo 100% com a última declaração de @spawnedc . Eu não esperaria que nenhuma propriedade fosse compartilhada entre instâncias de visualizações "irmãs".
Na verdade, nenhuma das propriedades é redefinida, a menos que sejam redefinidas no construtor. Eles são sempre as mesmas propriedades de protótipo compartilhadas por todas as instâncias criadas pelo mesmo construtor.
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
Se você estiver interessado, há uma ótima explicação aqui .
Não é exatamente isso que Bacbone está fazendo com itemArray neste caso? itemArray está no protótipo, é por isso que o comportamento que estamos experimentando está acontecendo?
Exatamente. É por isso que recomendo criar itemArray
em initialize
vez de como uma propriedade de protótipo.
@braddunbar Obrigado pela explicação e pelo link - Ainda é um comportamento estranho (e inesperado) por um lado, mas por outro lado, faz todo o sentido compartilhar as propriedades entre as visualizações.
Vou ler o artigo do JavaScript Garden e tenho certeza que tudo ficará claro :).
Comentários muito úteis
Sim, como
itemArray
é uma propriedade do protótipoitemView
, ele é compartilhado por todas as instâncias deitemView
. Se você deseja que as instâncias tenham seus própriositemArray
você deve defini-los eminitialize
ou no construtor.