Ext JS 4: Salvar Model/Store que tenha Associations (HasMany e HasOne)

22/11/2013 | By | 3 Comments

Olá pessoal,

Com a chegada do Ext JS 4, a Sencha introduziu as associações (Associations) no data package. Todo mundo ficou muito contente, mas infelizmente essa parte das Associations não foi 100% implementada como a comunidade esperou.

extjs associations writer loiane Ext JS 4: Salvar Model/Store que tenha Associations (HasMany e HasOne)

Só se pode carregar dados aninhados (nested data/json) usando Associations (você pode assistir um tutorial sobre isso aqui). Mas e a parte de salvar, enviar os dados aninhados de volta para o sever, como é que fica? Pois é, não fica, ou seja, não é possível via API nativa do Ext JS.

Mas…  a gente dá um jeito em tudo. Existem uns workarounds, maneiras de fazer isso funcionar. E não é gambiarra, é apenas modificar o código do Ext JS para que funcione do jeito que a gente quer.

Para salvar dados via data package existem duas formas: fazer um sync na Store ou chamar o método save do Model. O sync da Store é o mais usado e por isso vou mostrar esse workaround aqui.

Solução:

Basta criar um novo Writer com a funcionalidade de incluir os dados associados. Simples né?

Segue código:

Ext.define('AssociatedWriter', {
    extend: 'Ext.data.writer.Json',
    alias: 'writer.associatedjson',

    constructor: function(config) {
        this.callParent(arguments);
    },

    getRecordData: function (record, operation) {
        record.data = this.callParent(arguments);
        Ext.apply(record.data, record.getAssociatedData());
        return record.data;
    }
});

Você pode colocar esse código dentro da sua pasta app do seu projeto MVC sem problemas.

Exemplo de uso:

Considere que temos 2 Models: Contato e Telefone. Seguem os Models com Association:

Model Contato

Ext.define('Contato',{
    extend: 'Ext.data.Model',

    fields: [
            {name: 'id', type: 'int'},
            {name: 'nome', type: 'string'},
            {name: 'sobrenome', type: 'string'}
    ],

    hasMany: {model: 'Telefone', name: 'telefones', foreignKey: 'contatoId'}
});

Model Telefone

Ext.define('Telefone',{
    extend: 'Ext.data.Model',

    fields: [
            {name: 'id', type: 'int'},
            {name: 'ddd', type: 'string'},
            {name: 'numero', type: 'string'},
            {name: 'contatoId', type: 'int'}
    ]
});

Store Contatos

Ext.define('Contatos',{
    extend: 'Ext.data.Store',
    model: 'Contato',
    proxy: {
        type: 'ajax',

        api: {
            create: 'php/json/criaContato.php', //CRUD
            read: 'php/json/listaContatos.php',
            update: 'php/json/atualizaContato.php',
            destroy: 'php/json/deletaContato.php',
        },

        reader: {
            type: 'json',
            root: 'contatos'
        },

        writer: {
            type: 'associatedjson', //nosso Writer customizado
            root: 'contatos',
            writeAllFields: true,
            encode: true,
            allowSingle: false
        }
    }
});

Código de Teste

Ext.onReady(function(){

    var store = Ext.create('Contatos');

    var novoTelefone01 = Ext.create('Telefone',{
    	ddd: '11',
    	numero: '9 9999-9999'
    });

    var novoTelefone02 = Ext.create('Telefone',{
    	ddd: '11',
    	numero: '9 8888-8888'
    });

    var novoContato = Ext.create('Contato',{
    	nome: 'Loiane',
    	sobrenome: 'Groner'
    });

    novoContato.telefones().add(novoTelefone01);
    novoContato.telefones().add(novoTelefone02);

    store.add(novoContato);

    store.sync();
});

E se a gente usar o nosso Writer customizado na Store, vamos enviar dados assim para o server:

extjs associations writer Ext JS 4: Salvar Model/Store que tenha Associations (HasMany e HasOne)

E no server basta fazer o decode do JSON:

{
   contatos:[
      {
         "id":0,
         "nome":"Loiane",
         "sobrenome":"Groner",
         "telefones":[
            {
               "id":0,
               "ddd":"11",
               "numero":"9 9999-9999",
               "contatoId":0
            },
            {
               "id":0,
               "ddd":"11",
               "numero":"9 8888-8888",
               "contatoId":0
            }
         ]
      }
   ]
}

Parece complicado, mas na verdade é bem simples! icon smile Ext JS 4: Salvar Model/Store que tenha Associations (HasMany e HasOne)

Bem, é isso!

Pra quem quiser fazer download do Writer customizado e do arquivo de exemplo, segue repositório do github: https://github.com/loiane/extjs-associations-writer

Até a próxima! icon smile Ext JS 4: Salvar Model/Store que tenha Associations (HasMany e HasOne)

Filed in: Ext JS 4 | Tags: , , , , , ,

Comments (3)

  1. Loiane, nesse caso funciona em relacionamentos com muitos níveis?
    Ex:
    Instituicao:


    pessoaJuridica:


    pessoa:

  2. nesse caso precisa fazer uma recursão dentro do writer para pegar os dados em mais níveis.

  3. Fino d+ como sempre ajudando a todos nós a entender um pouco mais de ExtJS.

    Parabéns

Deixe um comentário