Tenho uma pergunta simples sobre as funções get e set do Backbone.js .
1) Com o código abaixo, como posso 'obter' ou 'definir' obj1.myAttribute1 diretamente?
Outra pergunta:
2) No Model, além do objeto defaults , onde posso / devo declarar os outros atributos do meu modelo, de forma que eles possam ser acessados através dos métodos get e set do Backbone?
var MyModel = Backbone.Model.extend({
defaults: {
obj1 : {
"myAttribute1" : false,
"myAttribute2" : true,
}
}
})
var MyView = Backbone.View.extend({
myFunc: function(){
console.log(this.model.get("obj1"));
//returns the obj1 object
//but how do I get obj1.myAttribute1 directly so that it returns false?
}
});
Eu sei que posso fazer:
this.model.get("obj1").myAttribute1;
mas isso é uma boa prática?
javascript
backbone.js
backbone-model
fortunaRice
fonte
fonte
defaults
(obj1 neste caso), esse mesmo objeto será compartilhado por todas as instâncias do modelo. A prática atual é definirdefaults
como uma função que retorna um objeto para ser usado como padrão. backbonejs.org/#Model-defaults (veja a nota em itálico)Respostas:
Embora
this.model.get("obj1").myAttribute1
esteja bem, é um pouco problemático porque então você pode ser tentado a fazer o mesmo tipo de coisa para o conjunto, ou seja,Mas se você fizer isso, não obterá os benefícios dos modelos de Backbone
myAttribute1
, como eventos de mudança ou validação.Uma solução melhor seria nunca aninhar POJSOs ("objetos JavaScript simples e antigos") em seus modelos e, em vez disso, aninhar classes de modelos personalizados. Portanto, seria algo assim:
Então, o código de acesso seria
mas o mais importante, o código de configuração seria
que irá disparar eventos de mudança apropriados e similares. Exemplo de trabalho aqui: http://jsfiddle.net/g3U7j/
fonte
Uncaught TypeError: Object #<Object> has no method 'set'
Backbone.Model
e, em seguida, começam a fazer bolhas de eventos mágicos.Criei um modelo profundo de backbone para isso - basta estender Backbone.DeepModel em vez de Backbone.Model e você pode usar caminhos para obter / definir atributos de modelo aninhados. Ele também mantém eventos de mudança.
fonte
//You can use index notation to fetch from arrays console.log(model.get('otherSpies.0.name')) //'Lana'
A solução de Domenic funcionará, no entanto, cada novo MyModel apontará para a mesma instância de Obj. Para evitar isso, MyModel deve ser semelhante a:
Veja a resposta de c3rin @ https://stackoverflow.com/a/6364480/1072653 para uma explicação completa.
fonte
Eu uso essa abordagem.
Se você tiver um modelo de Backbone como este:
Você pode definir o atributo "ab" com:
Agora seu modelo terá atributos como:
com o evento "alterar" disparado.
fonte
meta2= m.get('x'); meta2.id=110; m.set('x', meta2)
. Isso não aciona nenhum evento de alteração para mim :(_.clone(m.get('x'))
. obrigadosetting
com o objeto que você égetting
no tempo definido. Portanto, se você não clonar os dois objetos, os dois objetos sendo comparados serão exatamente os mesmos no tempo definido.Existe uma solução em que ninguém pensou ainda que é muito útil. De fato, você não pode definir atributos aninhados diretamente, a menos que use uma biblioteca de terceiros que provavelmente não deseja. No entanto, o que você pode fazer é fazer um clone do dicionário original, definir a propriedade aninhada lá e definir todo o dicionário. Pedaco de bolo.
fonte
Tive o mesmo problema que @pagewil e @Benno tiveram com a solução de @Domenic. Minha resposta foi, em vez disso, escrever uma subclasse simples de Backbone.Model que corrige o problema.
O que NestedModel faz por você é permitir que eles funcionem (que é o que acontece quando myModel é definido por meio de dados JSON):
Seria fácil gerar a lista de modelos automaticamente na inicialização, mas essa solução foi boa o suficiente para mim.
fonte
A solução proposta por Domenic tem alguns inconvenientes. Digamos que você queira ouvir o evento de 'mudança'. Nesse caso, o método 'inicializar' não será disparado e seu valor personalizado para o atributo será substituído pelo objeto json do servidor. No meu projeto, enfrentei esse problema. Minha solução para substituir o método 'definir' do modelo:
fonte
Embora em alguns casos o uso de modelos de backbone em vez de atributos de objeto aninhados faça sentido, como Domenic mencionou, em casos mais simples, você pode criar uma função setter no modelo:
fonte
Se você interagir com o back-end, o que requer objeto com estrutura de aninhamento. Mas com backbone mais fácil de trabalhar com estrutura linear.
backbone.linear pode ajudá-lo.
fonte