最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to load a nested model into a Extjs form using loadRecord - Stack Overflow

programmeradmin1浏览0评论

I've created a script to dynamically generate a form, but I'm having problem loading the data of the nested model. I've tried loading the whole record and I've tried loading each sub store, but neither works.

I've through about using form.load(), but from my understanding that requires a proxy connection and also require to store json data inside a 'data' array.

Does anyone have any suggestions on how might I approach this problem?

    <div id="view-@pageSpecificVar" class="grid-container even"></div>
<div id="button"></div>
<script>

    Ext.define('HeaderForm', {
        extend: 'Ext.form.Panel',
        initComponent: function () {
            var me = this;
            Ext.applyIf(me, {
                id: Ext.id(),
                defaultType: 'textfield'
            });
            me.callParent(arguments);
        }
    });

    // Define our data model
    Ext.define('HeaderModel', {
        extend: 'Ext.data.Model',
        fields: [
            { name: 'HeaderSequence', type: 'int'}
        ],
        hasMany:[
            { name: 'Columns', model: 'ColumnModel' }
        ],
        proxy: {
            type: 'ajax',
            actionMethods: { create: 'POST', read: 'GET', update: 'POST', destroy: 'POST' },
            url: '@Url.Content("~/Test/Header")',
            timeout: 1200000,
        },
    });

    Ext.define('ColumnModel', {
        extend: 'Ext.data.Model',
        fields: [
            { name: 'ColumnWidth', type: 'float'}
        ],
        hasMany:[
            { name: 'Fields', model: 'FieldModel'}
        ],
        belongsTo: 'HeaderModel'
    });

    Ext.define('FieldModel', {
        extend: 'Ext.data.Model',
        fields: [
            { name: 'XType', type: 'string'},
            { name: 'FieldLabel', type: 'string'},
            { name: 'Name', type: 'string'},
            { name: 'Data', type: 'string'},
            { name: 'FieldSpecify', type: 'bool'}
        ],
        belongsTo: 'ColumnModel'
    });

    var store = Ext.create('Ext.data.Store', {
        storeId: 'HeaderStore',
        model: 'HeaderModel',
        autoDestroy: true,
        listeners: {
            load: function (result, records, successful, eOpts) {
                //console.log(result);
                var form = dynamicForm(records[0]);
                form.add(submitButton);
                form.render('view-@pageSpecificVar');
            }
        }
    });

    store.load();

    var dynamicForm = function(record) {

        var form = new HeaderForm();
        var columnContainer = new Ext.widget({
            xtype: 'container',
            layout: 'column'
        });
        var formItems = new Ext.util.MixedCollection();

        Ext.each(record.ColumnsStore.data.items, function(item) {

            Ext.iterate(item.data, function (key, value) {


                var fieldContainer = new Ext.widget({
                    xtype: 'container',
                    columnWidth: value
                });

                Ext.each(item.FieldsStore.data.items, function(item) {
                    if(item.data["FieldSpecify"]) {
                        fieldContainer.add(new Ext.widget({
                            xtype: item.data["XType"],
                            fieldLabel: item.data["FieldLabel"],
                            name: item.data["Name"],
                            //value: item.data["Name"]
                        }));
                    }
                }, this);

                columnContainer.add(fieldContainer);

            }, this);

        }, this);

        formItems.add(columnContainer);

        form.add(formItems.items);

        Ext.each(record.ColumnsStore.data.items, function(item) {
            Ext.each(item.FieldsStore.data.items, function(fields) {
                form.loadRecord(fields);
            });
        });

        //form.loadRecord(record);

        return form;
    };

    var submitButton = new Ext.widget({
        xtype: 'toolbar',
        dock: 'bottom',
        items:[{
            xtype: 'button',
            text: 'Save',
            handler: function(button) {
                var basic = button.up('form').form;
                basic.updateRecord(basic.getRecord());
                var store = Ext.StoreMgr.get('HeaderStore');
                store.each(function(record) {
                    record.dirty = true;
                });
                store.sync();
            }
        }]
    });

</script>

Update Sorry I probably didn't made it very clear. I'm having problem loading the store data into form fields. For static forms I normally use loadRecord to load the nested model into a form, but in this case all the fields are nested in their own little model, so would there be a way to load each nested model value into their own field with loadRecord?

The HeaderModel stores field set information.

The purpose of ColumnModel is to create the container that will surround a set of fields, for styling purpose. It simply creates two columns of fields.

The FieldModel stores the field specific attributes and data.

Here's an example of response json data...

{
"HeaderSequence":1,
    "Columns":[{
        "ColumnWidth":0.5,"Fields":[
            {"XType":"textfield","FieldLabel":"FieldA","Name":"NameA","Data":"A","FieldSpecify":true},
            {"XType":"textfield","FieldLabel":"FieldB","Name":"NameA","Data":"B","FieldSpecify":true}]
        },{
        "ColumnWidth":0.5,"Fields":[
            {"XType":"textfield","FieldLabel":"FieldA2","Name":"NameA2","Data":"A2","FieldSpecify":true},
            {"XType":"textfield","FieldLabel":"FieldB2","Name":"NameB2","Data":"B2","FieldSpecify":true}]
        }   
]

}

Thanks

I've created a script to dynamically generate a form, but I'm having problem loading the data of the nested model. I've tried loading the whole record and I've tried loading each sub store, but neither works.

I've through about using form.load(), but from my understanding that requires a proxy connection and also require to store json data inside a 'data' array.

Does anyone have any suggestions on how might I approach this problem?

    <div id="view-@pageSpecificVar" class="grid-container even"></div>
<div id="button"></div>
<script>

    Ext.define('HeaderForm', {
        extend: 'Ext.form.Panel',
        initComponent: function () {
            var me = this;
            Ext.applyIf(me, {
                id: Ext.id(),
                defaultType: 'textfield'
            });
            me.callParent(arguments);
        }
    });

    // Define our data model
    Ext.define('HeaderModel', {
        extend: 'Ext.data.Model',
        fields: [
            { name: 'HeaderSequence', type: 'int'}
        ],
        hasMany:[
            { name: 'Columns', model: 'ColumnModel' }
        ],
        proxy: {
            type: 'ajax',
            actionMethods: { create: 'POST', read: 'GET', update: 'POST', destroy: 'POST' },
            url: '@Url.Content("~/Test/Header")',
            timeout: 1200000,
        },
    });

    Ext.define('ColumnModel', {
        extend: 'Ext.data.Model',
        fields: [
            { name: 'ColumnWidth', type: 'float'}
        ],
        hasMany:[
            { name: 'Fields', model: 'FieldModel'}
        ],
        belongsTo: 'HeaderModel'
    });

    Ext.define('FieldModel', {
        extend: 'Ext.data.Model',
        fields: [
            { name: 'XType', type: 'string'},
            { name: 'FieldLabel', type: 'string'},
            { name: 'Name', type: 'string'},
            { name: 'Data', type: 'string'},
            { name: 'FieldSpecify', type: 'bool'}
        ],
        belongsTo: 'ColumnModel'
    });

    var store = Ext.create('Ext.data.Store', {
        storeId: 'HeaderStore',
        model: 'HeaderModel',
        autoDestroy: true,
        listeners: {
            load: function (result, records, successful, eOpts) {
                //console.log(result);
                var form = dynamicForm(records[0]);
                form.add(submitButton);
                form.render('view-@pageSpecificVar');
            }
        }
    });

    store.load();

    var dynamicForm = function(record) {

        var form = new HeaderForm();
        var columnContainer = new Ext.widget({
            xtype: 'container',
            layout: 'column'
        });
        var formItems = new Ext.util.MixedCollection();

        Ext.each(record.ColumnsStore.data.items, function(item) {

            Ext.iterate(item.data, function (key, value) {


                var fieldContainer = new Ext.widget({
                    xtype: 'container',
                    columnWidth: value
                });

                Ext.each(item.FieldsStore.data.items, function(item) {
                    if(item.data["FieldSpecify"]) {
                        fieldContainer.add(new Ext.widget({
                            xtype: item.data["XType"],
                            fieldLabel: item.data["FieldLabel"],
                            name: item.data["Name"],
                            //value: item.data["Name"]
                        }));
                    }
                }, this);

                columnContainer.add(fieldContainer);

            }, this);

        }, this);

        formItems.add(columnContainer);

        form.add(formItems.items);

        Ext.each(record.ColumnsStore.data.items, function(item) {
            Ext.each(item.FieldsStore.data.items, function(fields) {
                form.loadRecord(fields);
            });
        });

        //form.loadRecord(record);

        return form;
    };

    var submitButton = new Ext.widget({
        xtype: 'toolbar',
        dock: 'bottom',
        items:[{
            xtype: 'button',
            text: 'Save',
            handler: function(button) {
                var basic = button.up('form').form;
                basic.updateRecord(basic.getRecord());
                var store = Ext.StoreMgr.get('HeaderStore');
                store.each(function(record) {
                    record.dirty = true;
                });
                store.sync();
            }
        }]
    });

</script>

Update Sorry I probably didn't made it very clear. I'm having problem loading the store data into form fields. For static forms I normally use loadRecord to load the nested model into a form, but in this case all the fields are nested in their own little model, so would there be a way to load each nested model value into their own field with loadRecord?

The HeaderModel stores field set information.

The purpose of ColumnModel is to create the container that will surround a set of fields, for styling purpose. It simply creates two columns of fields.

The FieldModel stores the field specific attributes and data.

Here's an example of response json data...

{
"HeaderSequence":1,
    "Columns":[{
        "ColumnWidth":0.5,"Fields":[
            {"XType":"textfield","FieldLabel":"FieldA","Name":"NameA","Data":"A","FieldSpecify":true},
            {"XType":"textfield","FieldLabel":"FieldB","Name":"NameA","Data":"B","FieldSpecify":true}]
        },{
        "ColumnWidth":0.5,"Fields":[
            {"XType":"textfield","FieldLabel":"FieldA2","Name":"NameA2","Data":"A2","FieldSpecify":true},
            {"XType":"textfield","FieldLabel":"FieldB2","Name":"NameB2","Data":"B2","FieldSpecify":true}]
        }   
]

}

Thanks

Share edited Oct 4, 2012 at 16:04 Jun Zheng asked Oct 4, 2012 at 8:48 Jun ZhengJun Zheng 6771 gold badge15 silver badges31 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 4

I've figure out how to load the nested model into the form. We can't simply use load or loadRecord, as by default that method tries to get a model's data and iterate through the data object and call setValues.

What I have to do is manually get the basic form element and call setValues myself to assign the values.

        // loop through each field store to load the data into the form by field id
        Ext.each(record.ColumnsStore.data.items, function(item) {
            Ext.each(item.FieldsStore.data.items, function(fields) {
                form.getForm().setValues([{ id: fields.data['Id'], value: fields.data['DisplayName'] }]);
            });
        });

To Follow up with that, a custom submit handler needs to be put in place as well. Which loops through the store and sets the submitted value to store before sync the store.

// define form submit button
    var submitButton = new Ext.widget({
        xtype: 'toolbar',
        dock: 'bottom',
        items:[{
            xtype: 'button',
            text: 'Save',
            handler: function(button) {
                // get basic form for button
                var basic = button.up('form').form;
                // get form submit values
                var formSubmitValues = basic.getValues();
                // get header store
                var store = Ext.StoreMgr.get('HeaderStore');
                // loop through each field store and update the data values by id from the form
                store.each(function(record) {
                    Ext.each(record.ColumnsStore.data.items, function(item) {
                        Ext.each(item.FieldsStore.data.items, function(fields) {
                            fields.data['Data'] = formSubmitValues[fields.data['Id']];
                        });
                    });
                    // mark the record as dirty to be sync
                    record.dirty = true;
                });
                // sync store object with the database
                store.sync();
            }
        }]
    });

Have a look at this and this examples on how to load nested data into a nested model. You will also see how to access the associated data.

I'm not sure why you use record.ColumnsStore.data.items, as if record is of HeaderModel type, you should really get the columns store via record.Columns, and then iterate that store.

Would also help to see what JSON your server returns.

发布评论

评论列表(0)

  1. 暂无评论