1

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

在煎茶论坛上也问过,我很绝望:

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

我将在这里编写所有我能写的代码,希望你们中的一些人会发现我做错了什么。

文中强调问题。

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

[
    {
        "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 架构,从教程中逐条注释,但惨遭失败。

我究竟做错了什么?

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

4

1 回答 1

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、...

提前感谢您的任何回答。

于 2012-08-06T08:56:52.917 回答