加载关联和绑定网格以形成

时间:2012-08-02 13:51:17

标签: json extjs extjs4 associations

之前我曾问过类似的问题:https://stackoverflow.com/questions/11707007/nested-json-form-submits-in-extjs4-getting-the-writer-to-remap-the-fields

在Sencha论坛上也问过,我非常绝望:

我在将嵌套的json文件读写到关联模型时遇到了很多问题。

我会在这里写下所有代码,希望你们中的一些人能找到我做错的事。

案文中强调了问题。

我收到的json看起来像这样,并且无法更改:tests:

[
    {
        "name":"qwerty",
        "id":"1",
        "uid":"1",
        "created":"1341481071",
        "changed":"1343804076",
        "status":"1",
        "jmeterOptions":{
            "jmx":"\/files\/20141\/multi.jmx",
            "engines":"0",
            "version":"2.5.1",
            "consoleArgs":" -t sample.jmx -JDelay=10000 -JEmbedded=1 -JRampup=1800 -JUsers=10",
            "engineArgs":" -JDelay=10000 -JEmbedded=1 -JRampup=1800 -JUsers=10",
            "instanceType":"m1.medium",
            "overrideOptions":{
                "threads":"50",
                "rampUpTime":"300",
                "iterations":"-1",
                "duration":"-1"
            }
        },
        "testOptions":{
            "type":"BM_TEST_TYPE_AUTO",
            "geo":"us-east-1",
            "timeout":"1",
            "reportByEmail":"1",
            "launchTime":"0",
            "sessionId":"",
            "hosts":null,
            "privateIps":null
        },
        "autoOptions":{
            "users":"10",
            "delay":"10",
            "rampUpTime":"1800",
            "pages":[
                {
                    "label":"sencha",
                    "url":"http:\/\/sencha.com"
                }
            ]
        },
        "seleniumOptions":{
            "pages":[
                {
                    "label":"sencha",
                    "url":"http:\/\/sencha.com"
                }
            ]
        }
    },
    {
        "name":"Instant Load test",
        "id":"2",
        "uid":"1",
        "created":"1336921297",
        "changed":"1341132949",
        "status":"1",
        "jmeterOptions":{
            "jmx":null,
            "engines":"0",
            "version":"2.5.1",
            "consoleArgs":" -t sample.jmx -JDelay=10000 -JEmbedded=1 -JRampup=1800 -JUsers=10",
            "engineArgs":" -JDelay=10000 -JEmbedded=1 -JRampup=1800 -JUsers=10",
            "instanceType":"m1.medium",
            "overrideOptions":null
        },
        "testOptions":{
            "type":"BM_TEST_TYPE_AUTO",
            "geo":null,
            "timeout":"1",
            "reportByEmail":"0",
            "launchTime":"0",
            "sessionId":"",
            "hosts":null,
            "privateIps":null
        },
        "autoOptions":{
            "users":"10",
            "delay":"10",
            "rampUpTime":"1800",
            "pages":[
                {
                    "label":"",
                    "url":"http:\/\/cnn.com"
                }
            ]
        },
        "seleniumOptions":{
            "pages":[
                {
                    "label":"",
                    "url":"http:\/\/cnn.com"
                }
            ]
        }
    }
]

该模型如下所示:

 Ext.define('BM.model.Test', {
    extend: 'Ext.data.Model',
    fields: [
        {name: 'name', type: 'string'},
        {name: 'id', type: 'id'},
        {name: 'uid', type: 'mumber'},
        {name: 'created', type: 'date', dateFormat: 'timestamp'},
        {name: 'changed', type: 'date', dateFormat: 'timestamp'},
        {name: 'status', type: 'number'},


        {name: 'jmeterJmx', mapping: 'jmeterOptions.jmx', type: 'string'},
        {name: 'jmeterEngines', mapping: 'jmeterOptions.engines', type: 'number'},
        {name: 'jmeterVersion', mapping: 'jmeterOptions.version', type: 'string'},
        {name: 'jmeterConsoleArgs', mapping: 'jmeterOptions.consoleArgs', type: 'string'},
        {name: 'jmeterEngineArgs', mapping: 'jmeterOptions.engineArgs', type: 'string'},
        {name: 'jmeterInstanceType', mapping: 'jmeterOptions.instanceType', type: 'string'},

        {name: 'testOptionsType', mapping: 'testOptions.type', type: 'string'},
        {name: 'testOptionsGeo', mapping: 'testOptions.geo', type: 'string'},
        {name: 'testOptionsTimeout', mapping: 'testOptions.timeout', type: 'number'},
        {name: 'testOptionsReportByEmail', mapping: 'testOptions.reportByEmail', type: 'string'},
        {name: 'testOptionsLaunchTime', mapping: 'testOptions.launchTime', type: 'string'},
        {name: 'testOptionsSessionId', mapping: 'testOptions.sessionId', type: 'string'},
        {name: 'testOptionsHosts', mapping: 'testOptions.hosts', type: 'string'},
        {name: 'testOptionsPrivateIps', mapping: 'testOptions.privateIps', type: 'string'},


        {name: 'autoUsers', mapping: 'autoOptions.users', type: 'number'},
        {name: 'autoDelay', mapping: 'autoOptions.delay', type: 'number'},
        {name: 'autoRampUpTime', mapping: 'autoOptions.rampUpTime', type: 'number'}
    ],


    hasMany: [
        {model: 'Pages', name: 'autoPages', associationKey: 'autoOptions.pages'},
        {model: 'Pages', name: 'seleniumPages', associationKey: 'seleniumOptions.pages'}
    ],


    proxy: {
        type: 'ajax',
        api: {
            read: '../webapp/get/tests',
            update: '../webapp/set/test'
        },
        reader: {
            type: 'json',
            root: 'tests',
            successProperty: 'success'
        },
        writer: new Ext.data.JsonWriter({
            encode: false,
            writeAllFields: true,
            getRecordData: function (record) {
                Ext.apply(record.data,record.getAssociatedData(true));
                return record.getAssociatedData(true);
            }
        })
    }
});


Ext.define('Pages', {
    extend: 'Ext.data.Model',
    fields: [
        {name: 'label', type: 'string'},
        {name: 'url', type: 'string'}
    ]
});

第一个问题:包括以下四行导致网格加载为空,为什么?

{name: 'jmeterOverrideThreads', mapping: 'jmeterOptions.overrideOptions.threads', type: 'number'},
{name: 'jmeterOverrideRampUpTime', mapping: 'jmeterOptions.overrideOptions.rampUpTime', type: 'number'},
{name: 'jmeterOverrideIterations', mapping: 'jmeterOptions.overrideOptions.iterations', type: 'number'},
{name: 'jmeterOverrideDuration', mapping: 'jmeterOptions.overrideOptions.duration', type: 'number'},

第二个问题:相关数据显示为空。 rawData有如上所示的json,如何让getAssociatedData填充正确的数据? 更好的是,为什么我的协会没有工作?

第三个问题:作者现在只发送空的关联数据,如何发送所有数据,就像我收到的一样?

我对此的解决方案很难看:

    updateTest: function(button) {
        var form = button.up('panel');
        var record = form.getRecord(),
            values = form.getValues();


        record.set(values);


        var rd = record.data;


//        this.getTestsStore().sync();         //No! Sends flattened data.
//        var autoPages = record.getAssociatedData().autoPages; // Is currently empty
//        var seleniumPages = record.getAssociatedData().seleniumPages; // Is currently empty

        var autoPages = [];
        var seleniumPages = [];
        var iterator = 0;
        var autoPagesLabel = record.data['autoPagesLabel' + iterator];
        var autoPagesUrl = record.data['autoPagesUrl' + iterator];
        while (autoPagesLabel != undefined){
            autoPages.push({
                'label': autoPagesLabel,
                'url': autoPagesUrl
            });
            iterator++;
            autoPagesLabel = record.data['autoPagesLabel' + iterator];
            autoPagesUrl = record.data['autoPagesUrl' + iterator];
        }
        iterator = 0;
        var seleniumPagesLabel = record.data['seleniumPagesLabel' + iterator];
        var seleniumPagesUrl = record.data['seleniumPagesUrl' + iterator];
        while (seleniumPagesLabel != undefined){
            seleniumPages.push({
                'label': seleniumPagesLabel,
                'url': seleniumPagesUrl
            });
            iterator++;
            seleniumPagesLabel = record.data['seleniumPagesLabel' + iterator];
            seleniumPagesUrl = record.data['seleniumPagesUrl' + iterator];
        }



        var reformattedJson = {
            "name": rd.name,
            "id": rd.id,
            "uid": rd.uid,
            "created": rd.created,
            "changed": rd.changed,
            "status": rd.status,
            "jmeterOptions":{
                "jmx": rd.jmeterJmx,
                "engines": rd.jmeterEngines,
                "version": rd.jmeterVersion,
                "consoleArgs": rd.jmeterConsoleArgs,
                "engineArgs": rd.jmeterEngineArgs,
                "instanceType": rd.jmeterInstanceType,
                "overrideOptions": {
                    "threads": rd.jmeterOverrideThreads,
                    "rampUpTime": rd.jmeterOverrideRampUpTime,
                    "iterations": rd.jmeterOverrideIterations,
                    "duration": rd.jmeterOverrideDuration
                }
            },
            "testOptions":{
                "type": rd.testOptionsType,
                "geo": rd.testOptionsGeo,
                "timeout": rd.testOptionsTimeout,
                "reportByEmail": rd.testOptionsReportByEmail,
                "launchTime": rd.testOptionsLaunchTime,
                "sessionId": rd.testOptionsSessionId,
                "hosts": rd.testOptionsHosts,
                "privateIps": rd.testOptionsPrivateIps
            },
            "autoOptions":{
                "users": rd.autoUsers,
                "delay": rd.autoDelay,
                "rampUpTime": rd.autoRampUpTime,
                "pages": autoPages
            },
            "seleniumOptions":{
                "pages":seleniumPages
            }
        };


        Ext.Ajax.request({
            url: '../webapp/set/test',
            method:'Post',
            jsonData: reformattedJson,
            success: function(response){
                var text = response.responseText;
                // process server response here
                console.log('Post successfull!  ');
            }
        });
    }

这是表格:

Ext.define('BM.view.test.Edit', {
    extend: 'Ext.form.Panel',
    alias: 'widget.test-edit',

    layout: 'anchor',
    title: 'Edit Test',
    defaultType: 'textfield',

    items: [
            {name: 'id', hidden: true},
            {name: 'name', fieldLabel: 'Name'},
            {name: 'status', fieldLabel: 'Status'},
            {name: 'testOptionsType', fieldLabel: 'Type'},
            {name: 'autoUsers', fieldLabel: 'User count'}
        ],

     buttons: [
        {
            text: 'Save',
            action: 'save'
        },
        {
            text: 'Cancel',
            scope: this,
            handler: this.close
        }
    ]
});

这就是调用表格:(点击网格行)

editTest: function(grid, record) {
    var view = Ext.widget('test-edit');
    var viewPort = Ext.ComponentQuery.query('viewport')[0];

    var autoPages = record.raw.autoOptions.pages;
    var seleniumPages = record.raw.seleniumOptions.pages;
    for (var i =0; i < autoPages.length; i++){
        var tf = Ext.create('Ext.form.field.Text', {
            id: 'autoPagesLabel' + i,
            name: 'autoPagesLabel' + i,
            fieldLabel: 'Label',
            value: autoPages[i].label,
            columnWidth:0.5
        });
        view.add(tf);
        tf = Ext.create('Ext.form.field.Text', {
            id: 'autoPagesUrl' + i,
            name: 'autoPagesUrl' + i,
            fieldLabel: 'Url',
            value: autoPages[i].url,
            columnWidth:0.5
        });
        view.add(tf);
    }


    view.loadRecord(record);
    viewPort.layout.centerRegion.removeAll();
    viewPort.layout.centerRegion.add(view);
}

我试着遵循Ext JS 4的MVC架构,请注意教程中的注释,并且失败了。

我做错了什么?

您是否需要任何其他信息或代码?告诉我,我会发布它们。

1 个答案:

答案 0 :(得分:0)

我找到了一个适用于我的一些问题的解决方案。

作为我第一个问题的旁路,我发现两个以上级别的映射存在问题,因此我添加了一个hasOne关系。我不认为这是一个很好的解决方案,但没有其他人,会喜欢这个评论。

{name: 'jmeterOverrideThreads', mapping: 'jmeterOptions.overrideOptions.threads', type: 'number'},
{name: 'jmeterOverrideRampUpTime', mapping: 'jmeterOptions.overrideOptions.rampUpTime', type: 'number'},
{name: 'jmeterOverrideIterations', mapping: 'jmeterOptions.overrideOptions.iterations', type: 'number'},
{name: 'jmeterOverrideDuration', mapping: 'jmeterOptions.overrideOptions.duration', type: 'number'},

从模型中变为:

hasOne: [
        {model: 'OverrideOptions', associationKey: 'jmeterOptions', reader: {root: 'overrideOptions'}}
],

// and:

Ext.define('OverrideOptions', {
    extend: 'Ext.data.Model',
    fields: [
        {name: 'jmeterOverrideThreads', mapping: 'threads', type: 'number'},
        {name: 'jmeterOverrideRampUpTime', mapping: 'rampUpTime', type: 'number'},
        {name: 'jmeterOverrideIterations', mapping: 'iterations', type: 'number'},
        {name: 'jmeterOverrideDuration', mapping: 'duration', type: 'number'}
    ]
});

至于我关于不起作用的协会的第二个问题: 在我的模型中,而不是:

hasMany: [
        {model: 'Pages', name: 'autoPages', associationKey: 'autoOptions.pages'},
        {model: 'Pages', name: 'seleniumPages', associationKey: 'seleniumOptions.pages'}
],

我补充说:

hasMany: [
        {model: 'Pages', name: 'autoPages', associationKey: 'autoOptions', reader: {root: 'pages'}},
        {model: 'Pages', name: 'seleniumPages', associationKey: 'seleniumOptions', reader: {root: 'pages'}}
    ],

突然间,我能够从record.getAssociatedData()访问我的数据,它仍然被展平,但至少我有数据。

我仍然没有一个好主意让编写器以原始格式输出数据,而不是像我在暴力中那样编写数据。 会再次喜欢这方面的反馈。

出现了其他问题: 我希望将关联的数据添加到表单中。在我们讨论对象数组时,我们不知道会有多少对象,是否有更好的方法从关联数据创建表单,而不是我在原始问题中使用的表单。有没有更好的方法来访问表单数据,除了使用正在运行的迭代器命名字段:a1,a2,...

提前感谢您的回答。