Backbone: Os atributos de visualização personalizados são compartilhados entre diferentes instâncias

Criado em 19 abr. 2012  ·  9Comentários  ·  Fonte: jashkenas/backbone

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.

question

Comentários muito úteis

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 = [];
  },

  ...

});

Todos 9 comentários

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 :).

Esta página foi útil?
0 / 5 - 0 avaliações