Modelos aninhados em Backbone.js, como abordar
Eu tenho o seguinte JSON fornecido de um servidor. Com isso, quero criar um modelo com um modelo aninhado. Não tenho certeza de qual é a maneira de conseguir isso.
Quero que eles sejam convertidos em dois modelos de backbone aninhados com a seguinte estrutura:
Então, eu defino o modelo de Layout assim:
Mas qual das duas técnicas (se houver) abaixo devo usar para definir o modelo de imagem? A ou B abaixo?
Eu tenho o mesmo problema enquanto escrevo meu aplicativo Backbone. Ter que lidar com modelos embutidos / aninhados. Fiz alguns ajustes que achei uma solução bastante elegante.
Sim, você pode modificar o método de análise para alterar os atributos do objeto, mas tudo isso é, na verdade, um código IMO bastante insustentável e parece mais um hack do que uma solução.
Aqui está o que sugiro para o seu exemplo:
Primeiro defina seu modelo de layout como tal.
Então aqui está o seu modelo de imagem:
Observe que não adulterei o próprio modelo, mas apenas passei de volta o objeto desejado do método de análise.
Isso deve garantir a estrutura do modelo aninhado quando você estiver lendo do servidor. Agora, você notaria que salvar ou configurar não é tratado aqui porque acho que faz sentido para você definir o modelo aninhado explicitamente usando o modelo adequado.
Observe também que, na verdade, você está invocando o método de análise em seu modelo aninhado chamando:
Você pode definir quantos modelos aninhados no modelcampo forem necessários.
Claro, se você quiser ir tão longe quanto salvar o modelo aninhado em sua própria tabela. Isso não seria suficiente. Mas, no caso de ler e salvar o objeto como um todo, essa solução deve bastar.
— Rycfung
Isso é bom ... deve ser a resposta aceita, pois é muito mais limpa do que as outras abordagens. A única sugestão que eu teria é colocar a primeira letra de suas classes que estendem Backbone.Model para facilitar a leitura, ou seja, ImageModel e LayoutModel
— Stephen Handley,
@StephenHandley Obrigado pelo comentário e sua sugestão. Para a informação, estou usando isso no contexto de requireJS. Portanto, para responder à questão da capitalização, o var 'imageModel' é realmente retornado para requireJS. E a referência ao modelo seria encapsulada pela seguinte construção: define(['modelFile'], function(MyModel){... do something with MyModel}) Mas você está certo. Tenho o hábito de fazer referência ao modelo pela convenção que você sugeriu.
— rycfung,
@BobS Desculpe, foi um erro de digitação. Deveria haver resposta. Eu consertei, obrigado por apontar.
Agradável! Eu recomendo adicionar isso à Backbone.Model.prototype.parsefunção. Então, tudo que seus modelos precisam fazer é definir os tipos de objeto do submodelo (em seu atributo "modelo").
— Jasop
Legal! Acabei fazendo algo semelhante (notável e lamentavelmente depois de encontrar esta resposta) e escrevi aqui: blog.untrod.com/2013/08/declarative-approach-to-nesting.html A grande diferença é que para modelos profundamente aninhados Eu declaro todo o mapeamento de uma vez, no modelo raiz / pai, e o código o pega de lá e percorre todo o modelo, hidratando objetos relevantes em coleções e modelos de Backbone. Mas realmente uma abordagem muito semelhante.
Estou postando este código como um exemplo da sugestão de Peter Lyon para redefinir a análise. Eu tive a mesma dúvida e isso funcionou para mim (com um backend Rails). Este código foi escrito em Coffeescript. Eu deixei algumas coisas explícitas para pessoas não familiarizadas com ele.
ou, em JS
Suportes para o código de exemplo e sugestão de análise de substituição. Obrigado!
seria bom ter sua resposta em JS real
feliz por ter a versão coffeescript, obrigado. Para outros, tente js2coffee.org
Se a pergunta for JS real, uma resposta também deve ser.
Uso Backbone.AssociatedModelde associações de backbone :
— Jaynti Kanani
Ótima solução. Existe um projeto semelhante por aí também: github.com/PaulUithol/Backbone-relational
Não tenho certeza se o próprio Backbone tem uma maneira recomendada de fazer isso. O objeto Layout tem seu próprio ID e registro no banco de dados back end? Nesse caso, você pode torná-lo seu próprio modelo, como você fez. Caso contrário, você pode apenas deixá-lo como um documento aninhado, apenas certifique-se de convertê-lo de e para JSON corretamente nos métodos savee parse. Se você acabar adotando uma abordagem como esta, acho que seu exemplo A é mais consistente com o backbone, pois setserá atualizado corretamente attributes, mas, novamente, não tenho certeza do que o Backbone faz com os modelos aninhados por padrão. É provável que você precise de algum código personalizado para lidar com isso.
Ah! Desculpe, estava faltando a newoperadora. Eu editei para corrigir esse erro.
Oh, então eu interpretei mal sua pergunta. Vou atualizar minha resposta.
Eu escolheria a Opção B se você quiser manter as coisas simples.
Outra boa opção seria usar o Backbone-Relacional . Você apenas definiria algo como:
+1 Backbone-Releational parece bastante estabelecido: website próprio, 1.6k estrelas, mais de 200 garfos.
Eu uso o plugin Backbone DeepModel para modelos e atributos aninhados.
Você pode vincular a eventos de mudança em níveis de profundidade. por exemplo: model.on('change:example.nestedmodel.attribute', this.myFunction);
Versão CoffeeScript da bela resposta de rycfung :
Eu não aceito açúcar no meu JavaScript
Eu tive o mesmo problema e estou testando o código da resposta de rycfung , o que é uma ótima sugestão.
Se, no entanto, você não quiser setos modelos aninhados diretamente, ou não quiser passar constantemente {parse: true}no options, outra abordagem seria redefinir a setsi mesmo.
Em Backbone 1.0.0 , seté chamado constructor, unset, clear, fetche save.
Considere o seguinte super modelo , para todos os modelos que precisam aninhar modelos e / ou coleções.
Observe isso model, _setModele _unsetModelsão deixados em branco propositalmente. Nesse nível de abstração, você provavelmente não pode definir nenhuma ação razoável para os callbacks. No entanto, você pode querer substituí-los nos submodelos dessa extensão CompoundModel.
Esses retornos de chamada são úteis, por exemplo, para vincular ouvintes e propagar changeeventos.
Com isso, você tem criação automática de modelo aninhado e propagação de eventos. O uso de amostra também é fornecido e testado:
Sei que estou atrasado para esta festa, mas recentemente lançamos um plugin para lidar exatamente com esse cenário. É chamado de backbone-nestify .
Portanto, seu modelo aninhado permanece inalterado:
Em seguida, use o plug-in ao definir o modelo contido (usando Underscore.extend ):
Depois disso, supondo que você tenha um modelo mque seja uma instância de Imagee tenha definido o JSON a partir da pergunta m, você pode fazer:
— Scott Bale
Use formulários de backbone
Ele suporta formulários aninhados, modelos e toJSON. TODOS ANINHADOS
— David Rz Ayala
Se você não quiser adicionar outra estrutura, pode considerar a criação de uma classe base com sete substituída toJSONe usá-la assim:
Você precisará BaseModeldesta resposta (disponível, se desejar, como uma essência ).
Também temos esse problema e um trabalhador da equipe implementou um plugin chamado backbone-nested-atributos.