How to link models (with association), forms and grids in ExtJS 4?

14

I'm using ExtJS 4.2 in a project and I'm having problems involving model associations and how to link them to forms and grids. I'll illustrate with an example.

I have 3 classes and 1 json, as below:

User

Ext.define('Usuario', {
    extend: 'Ext.data.Model',
    fields: ['id', 'nome'],

    hasMany: { model: 'Telefone', name: 'telefones' }
    hasOne: { model: 'Endereco', name: 'endereco'}
});

Address

Ext.define('Endereco', {
    extend: 'Ext.data.Model',
    fields: ['id', 'logradouro', 'endereco', 'numero', 'cidade', 'estado', 'usuario_id']
});

Phone

Ext.define('Telefone', {
    extend: 'Ext.data.Model',
    fields: ['id', 'ddd', 'numero', 'usuario_id'],
});

Json users

{
    "data": [
        {
            "id": 1,
            "nome": "Maria",
            "telefones": [
                {
                    "id": 1,
                    "ddd": 11,
                    "numero": 33445566
                },
                {
                    "id": 2,
                    "ddd": 12,
                    "numero": 988887777
                }
            ],
            "endereco": {
                "id": 1,
                "logradouro": "Rua",
                "endereco": "Santa Rosa",
                "numero": 6
            }
        }
    ]
}

The problem began when I needed to save nested data. Then I found the Loiane Groner blog a post about saving nested data . It worked! There came another, bigger problem: how to link a model with associations to a form and grid? And then, how to save the form data using the model and its already configured proxy?

I've seen a lot of people in the form itself a submit with the url and proxy to be used, but if using MVC I've already created my model, store and proxy, because I must reassemble the proxy in form and ignore my structure already done? I would like to use the features I have implemented in model, store and proxy ...

Well, I found a text that shows how to link (in the case of form) , but I'm having trouble understanding its solution and it does not seem to work for model with hasOne association.

    
asked by anonymous 17.12.2013 / 18:41

1 answer

3

You can build a grid using renderer of columns .

Ext.create('Ext.grid.Panel', {
    title: 'Usuários',
    store: store,
    columns: [{
        text: 'Nome',
        dataIndex: 'nome'
    },{
        text: 'Telefones',
        renderer: function (val, meta, record) {
            var tel = '';
            record.telefones().each(function(telRecord, index, count) {
                if(tel.length>0) tel = tel + '; '
                tel = tel + '(' + telRecord.get('ddd') + ') ' + telRecord.get('numero');
            });
            return tel;
        }
    },{
        text: 'Endereço',
        renderer: function (val, meta, record) {
            var obj = record.getEndereco().data;
            var enderecos = '';
            enderecos = enderecos + obj.logradouro;
            enderecos = enderecos + ' ' + obj.endereco;
            enderecos = enderecos + ' ' + obj.numero;
            enderecos = enderecos + ' - ' + obj.cidade;
            return enderecos;
        }
    }

             ],
    height: 200,
    width: 500,
    renderTo: Ext.getBody()
});

Example ( jsfiddle ):

Ext.define('Usuario', {
    extend: 'Ext.data.Model',
    fields: ['id', 'nome'],

    hasMany: { model: 'Telefone', name: 'telefones' },
    hasOne: { model: 'Endereco', name: 'endereco'}
});

Ext.define('Endereco', {
    extend: 'Ext.data.Model',
    fields: ['id', 'logradouro', 'endereco', 'numero', 'cidade', 'estado', 'usuario_id']
});

Ext.define('Telefone', {
    extend: 'Ext.data.Model',
    fields: ['id', 'ddd', 'numero', 'usuario_id']
});


var data = {
    "success": "true",
    "data": [
        {
            "id": 1,
            "nome": "Maria",
            "telefones": [
                {
                    "id": 1,
                    "ddd": 11,
                    "numero": 33445566
                },
                {
                    "id": 2,
                    "ddd": 12,
                    "numero": 988887777
                }
            ],
            "endereco": {
                "id": 1,
                "logradouro": "Rua",
                "endereco": "Santa Rosa",
                "numero": 6
            }
        }
    ]
};

var store = Ext.create('Ext.data.Store', {
    model: "Usuario",
    autoLoad: true,
    data: data,
    proxy: {
        type: 'memory',
        reader: {
            type: 'json',
            root: 'data',
            successProperty: 'success'
        }
    }
});

Ext.create('Ext.grid.Panel', {
    title: 'Usuários',
    store: store,
    columns: [{
        text: 'Nome',
        dataIndex: 'nome'
    },{
        text: 'Telefones',
        renderer: function (val, meta, record) {
            var tel = '';
            record.telefones().each(function(telRecord, index, count) {
                if(tel.length>0) tel = tel + '; '
                tel = tel + '(' + telRecord.get('ddd') + ') ' + telRecord.get('numero');
            });
            return tel;
        }
    },{
        text: 'Endereço',
        renderer: function (val, meta, record) {
            var obj = record.getEndereco().data;
            var enderecos = '';
            enderecos = enderecos + obj.logradouro;
            enderecos = enderecos + ' ' + obj.endereco;
            enderecos = enderecos + ' ' + obj.numero;
            enderecos = enderecos + ' - ' + obj.cidade;
            return enderecos;
        }
    }
             
             ],
    height: 200,
    width: 500,
    renderTo: Ext.getBody()
});
<link rel="stylesheet" type="text/css" href="//cdnjs.cloudflare.com/ajax/libs/extjs/4.2.1/resources/css/ext-all-debug.css"
/>
<script type='text/javascript' src='//cdnjs.cloudflare.com/ajax/libs/extjs/4.2.1/ext-all.js'></script>
    
02.02.2014 / 07:17