【问题标题】:How can I render nested JSON in Sencha?如何在 Sencha 中渲染嵌套的 JSON?
【发布时间】:2013-10-25 01:27:25
【问题描述】:

我有一个格式正确的 JSON 文件,因为当我将它加载到在线 JSON 查看器中时,树会呈现:

现在我想使用 Sencha ExtJS 做一些类似的事情,但较低的级别不呈现:

即使我将所有节点重命名为“children”,问题也是一样的。当我尝试扩展树的第二级时,从 firebug 收到此错误:

TypeError: records[i] is undefined


ns[i].viewRecordId = records[i].internalId;

ext-all-debug.js (line 60517)

错误是什么意思?我的代码是

/*
 * File: app/controller/CheckNode.js
 *
 * This file was generated by Sencha Architect version 2.2.3.
 * http://www.sencha.com/products/architect/
 *
 * This file requires use of the Ext JS 4.0.x library, under independent license.
 * License of Sencha Architect does not include license for Ext JS 4.0.x. For more
 * details see http://www.sencha.com/license or contact license@sencha.com.
 *
 * This file will be auto-generated each and everytime you save your project.
 *
 * Do NOT hand edit this file.
 */

Ext.define('MyApp.controller.CheckNode', {
    extend: 'Ext.app.Controller',

    models: [
        'CheckNode'
    ],
    stores: [
        'CheckNodes'
    ],
    views: [
        'CheckedNodeTree'
    ],

    refs: [
        {
            ref: 'checkedTree',
            selector: 'checkedtree'
        }
    ],

    onButtonClick: function(button, e, eOpts) {
        var records = this.getCheckedTree().getView().getChecked(),
            names = [];

        Ext.Array.each(records, function(rec){
            names.push(rec.get('text'));
        });

        Ext.MessageBox.show({
            title: 'TODO',
            msg: names.join('<br />Not implemented'),
            icon: Ext.MessageBox.INFO
        });    
    },

    init: function(application) {
        this.control({
            "button[action='getCheckedNodes']": {
                click: this.onButtonClick
            }
        });
    }

});

/*
 * File: app/model/CheckNode.js
 *
 * This file was generated by Sencha Architect version 2.2.3.
 * http://www.sencha.com/products/architect/
 *
 * This file requires use of the Ext JS 4.0.x library, under independent license.
 * License of Sencha Architect does not include license for Ext JS 4.0.x. For more
 * details see http://www.sencha.com/license or contact license@sencha.com.
 *
 * This file will be auto-generated each and everytime you save your project.
 *
 * Do NOT hand edit this file.
 */

Ext.define('MyApp.model.CheckNode', {
    extend: 'Ext.data.Model',

    fields: [
        {
            name: 'name'
        }
    ]
});
/*
 * File: app/store/CheckNodes.js
 *
 * This file was generated by Sencha Architect version 2.2.3.
 * http://www.sencha.com/products/architect/
 *
 * This file requires use of the Ext JS 4.0.x library, under independent license.
 * License of Sencha Architect does not include license for Ext JS 4.0.x. For more
 * details see http://www.sencha.com/license or contact license@sencha.com.
 *
 * This file will be auto-generated each and everytime you save your project.
 *
 * Do NOT hand edit this file.
 */

Ext.define('MyApp.store.CheckNodes', {
    extend: 'Ext.data.TreeStore',

    requires: [
        'MyApp.model.CheckNode'
    ],

    constructor: function(cfg) {
        var me = this;
        cfg = cfg || {};
        me.callParent([Ext.apply({
            autoLoad: true,
            model: 'MyApp.model.CheckNode',
            storeId: 'CheckNodes',
            proxy: {
                type: 'ajax',
                url: 'data/tree.json'
            }
        }, cfg)]);
    }
});

/*
 * File: app/view/CheckedNodeTree.js
 *
 * This file was generated by Sencha Architect version 2.2.3.
 * http://www.sencha.com/products/architect/
 *
 * This file requires use of the Ext JS 4.0.x library, under independent license.
 * License of Sencha Architect does not include license for Ext JS 4.0.x. For more
 * details see http://www.sencha.com/license or contact license@sencha.com.
 *
 * This file will be auto-generated each and everytime you save your project.
 *
 * Do NOT hand edit this file.
 */

Ext.define('MyApp.view.CheckedNodeTree', {
    extend: 'Ext.tree.Panel',
    alias: 'widget.checkedtree',

    frame: true,
    height: 400,
    width: 640,
    title: 'Product Offerings',
    store: 'CheckNodes',
    displayField: 'name',
    lines: false,
    rootVisible: false,

    initComponent: function() {
        var me = this;

        Ext.applyIf(me, {
            viewConfig: {

            },
            dockedItems: [
                {
                    xtype: 'toolbar',
                    dock: 'top',
                    items: [
                        {
                            xtype: 'button',
                            action: 'getCheckedNodes',
                            text: 'Add new'
                        }
                    ]
                }
            ]
        });

        me.callParent(arguments);
    }

});

/*
 * File: app/view/Viewport.js
 *
 * This file was generated by Sencha Architect version 2.2.3.
 * http://www.sencha.com/products/architect/
 *
 * This file requires use of the Ext JS 4.0.x library, under independent license.
 * License of Sencha Architect does not include license for Ext JS 4.0.x. For more
 * details see http://www.sencha.com/license or contact license@sencha.com.
 *
 * This file will be auto-generated each and everytime you save your project.
 *
 * Do NOT hand edit this file.
 */

Ext.define('MyApp.view.Viewport', {
    extend: 'MyApp.view.CheckedNodeTree',
    renderTo: Ext.getBody()
});

JSON文件的开头是

{"productOfferings":[{"@class":"BundledProductOffering","id":26,"name":"Mobile subscription with Internet access 2GB and iPad 32GB","description":"Joors 2GB mobile broadband and iPad 32GB","status":null,"brand":{"id":"Joors SE"},"validFor":{"startDateTime":1382514501359,"endDateTime":null},"productOfferings":[{"@class":"SimpleProductOffering","id":5,"name":"Ipad with 32 GB storage","description":"A iPad 32 GB Product Offering","status":"active","brand":{"id":"Joors SE"},"validFor":{"startDateTime":1382514501222,"endDateTime":null},"productSpecification":{"@class":"MobileProductSpecification","id":5,"name":"IPad","description":"","productNumber":"1234567","validFor":{"startDateTime":1382514501111,"endDateTime":null},"brand":{"id":"Joors SE"},"characteristics":null,"resourceSpecification":{"@class":"PhysicalDeviceSpecification","id":13,"resourceCapacity":null,"logicalResourceSpecification":null,"modelNumber":"A1460","partNumber":null,"skuNumber":null,"vendorName":"Apple","tags":[{"name":"hardware","value":"IPad"},{"name":"hardwareCategory","value":"tablet"},{"name":"hardwareBrand","value":"Apple"}],"descriptorId":null,"characteristics":[{"id":1,"name":"Color","description":null,"minCardinality":null,"maxCardinality":null,"validFor":null,"values":[{"valueType":"COLOR","defaultValue":false,"value":"WHITE","valueFrom":null,"valueTo":null,"unitOfMeasure":null,"validFor":{"startDateTime":1382514500714,"endDateTime":null}},{"valueType":"COLOR","defaultValue":false,"value":"BLACK","valueFrom":null,"valueTo":null,"unitOfMeasure":null,"validFor":{"startDateTime":1382514500713,"endDateTime":null}}],"valueType":null,"descriptorId":null},{"id":2,"name":"Storage size","description":null,"minCardinality":null,"maxCardinality":null,"validFor":null,"values":[{"valueType":"INTEGER","defaultValue":false,"value":"32","valueFrom":null,"valueTo":null,"unitOfMeasure":"GB","validFor":{"startDateTime":1382514500745,"endDateTime":null}},{"valueType":"INTEGER","defaultValue":false,"value":"16","valueFrom":null,"valueTo":null,"unitOfMeasure":"GB","validFor":{"startDateTime":1382514500745,"endDateTime":null}}],"valueType":null,"descriptorId":null}]},"serviceSpecification":null,"lifecycleStatus":null,"mobileNetworkOperator":{"id":2,"name":"Tele2 Sweden","mobileCountryCode":"240","mobileNetworkCode":"07","issuerIdentificationNumber":"894607","country":{"name":"Sweden","code":"SE"}},"tags":null,"descriptorId":null},"descriptorId":null,"tags":null,"productOfferingPrice":{"@class":"ProductOfferingPriceChargeDto","id":4,"description":"The price when buying a iPad with 32 GB memory together with a subscription","name":"iPad 32 GB product offering price","validFor":{"startDateTime":1382514501222,"endDateTime":null},"productSpecificationId":5,"productSpecificationCharacteristicValueUse":null,"resourceSpecificationCharacteristicValueUse":{"productOfferingReference":{"id":5,"name":"Ipad with 32 GB storage","sortOrder":null},"productSpecificationReference":{"id":5,"name":"IPad","sortOrder":null},"resourceSpecificationReference":{"id":13,"name":"iPad with Retina","sortOrder":null},"resourceSpecificationCharacteristicReference":{"id":2,"name":"Storage size","sortOrder":null},"resourceSpecificationCharacteristicValueDto":{"valueType":"INTEGER","defaultValue":false,"value":"32","valueFrom":null,"valueTo":null,"unitOfMeasure":"GB","validFor":{"startDateTime":1382514500745,"endDateTime":null}}},"serviceSpecificationCharacteristicValueUse":null,"money":{"amount":6890.00,"currency":"SEK"},"unitOfMeasure":{"amount":1,"units":"PIECE"}}},{"@class":"SimpleProductOffering","id":8,"name":"Mobile subscription with Sim Card and Internet access 2GB","description":"Mobile subscription with Sim Card and Internet access 2GB","status":"active","brand":{"id":"Joors SE"},"validFor":{"startDateTime":1382514501068,"endDateTime":null},"productSpecification":{"@class":"ProductSpecificationComposite","id":9,"name":"Mobile subscription with sim card and Internet access","description":"Mobile subscription with sim card and Internet access","productNumber":null,"validFor":{"startDateTime":1382514501068,"endDateTime":null},"brand":{"id":"Joors SE"},"characteristics":null,"resourceSpecification":null,"serviceSpecification":null,"productSpecifications":[{"@class":"MobileTelephonyProductSpecification","id":2,"name":"Mobile subscription with Sim Card","description":"This is the classic Subscription product of a Mobile Network totally void of Services, so it can only be used for accessing a HPLMN. Simply put a MSISDN + SIM","productNumber":null,"validFor":{"startDateTime":1382514501068,"endDateTime":null},"brand":{"id":"Joors SE"},"characteristics":null,"resourceSpecification":{"@class":"CompoundResourceSpecificationDto","id":15,"characteristics":null,"resourceSpecifications":[{"@class":"PhysicalSimCardResourceSpecification","id":1,"resourceCapacity":null,"logicalResourceSpecification":null,"modelNumber":null,"partNumber":"163","skuNumber":null,"vendorName":"Stralfors","name":"Sim Card","cardCarrier":"full-size","format":"Full size sim","uiccPartNumber":"","tags":null,"descriptorId":null,"characteristics":[]},{"@class":"MsisdnResourceSpecification","id":11,"resourceCapacity":null,"characteristics":[],"msisdnRegExp":".*","tags":null,"descriptorId":null}],"tags":null,"descriptorId":null,"resourceCapacity":null},"serviceSpecification":null,"lifecycleStatus":"active","mobileNetworkOperator":{"id":2,"name":"Tele2 Sweden","mobileCountryCode":"240","mobileNetworkCode":"07","issuerIdentificationNumber":"894607","country":{"name":"Sweden","code":"SE"}},"tags":[{"name":"subscription","value":"standard"}],"descriptorId":null},{"@class":"MobileProductSpecification","id":4,"name":"Mobile Internet access","description":"This is a GPRS Service for a Mobile Network Access Product for accessing Internet","productNumber":null,"validFor":{"startDateTime":1382514501106,"endDateTime":null},"brand":{"id":"Joors SE"},"characteristics":null,"resourceSpecification":null,"serviceSpecification":{"@class":"CompositeServiceSpecification","id":null,"name":"Joors Packet Data Access Service","description":null,"characteristics":null,"tags":null,"version":1,"serviceSpecifications":[{"@class":"MobilePacketDataNetworkAccessServiceSpecificationAtomic","id":1,"name":"Joors Domain Packet Data Access Service","description":null,"characteristics":[{"id":1,"name":"Quality of service max bandwidth","description":"Quality of service max bandwidth","minCardinality":null,"maxCardinality":null,"validFor":null,"values":[{"valueType":"FLOAT","defaultValue":false,"value":"10.0","valueFrom":null,"valueTo":null,"unitOfMeasure":"MBPS","validFor":null}],"valueType":"FLOAT","descriptorId":null}],"tags":null,"version":1,"sourceNetwork":"HPLMN","destinationNetwork":"joors.com","descriptorId":null,"mobileNetworkOperator":{"id":1,"name":"TeliaSoneraSE","mobileCountryCode":"240","mobileNetworkCode":"01","issuerIdentificationNumber":"894601","country":{"name":"Sweden","code":"SE"}}},{"@class":"MobilePacketDataNetworkAccessServiceSpecificationAtomic","id":2,"name":"Default Packet Data Access Service","description":null,"characteristics":[{"id":1,"name":"Quality of service max bandwidth","description":"Quality of service max bandwidth","minCardinality":null,"maxCardinality":null,"validFor":null,"values":[{"valueType":"FLOAT","defaultValue":false,"value":"10.0","valueFrom":null,"valueTo":null,"unitOfMeasure":"MBPS","validFor":null}],"valueType":"FLOAT","descriptorId":null}],"tags":null,"version":1,"sourceNetwork":"HPLMN","destinationNetwork":"*","descriptorId":null,"mobileNetworkOperator":{"id":1,"name":"TeliaSoneraSE","mobileCountryCode":"240","mobileNetworkCode":"01","issuerIdentificationNumber":"894601","country":{"name":"Sweden","code":"SE"}}},{"@class":"MobilePacketDataNetworkAccessServiceSpecificationAtomic","id":3,"name":"Fallback Packet Data Access Service","description":null,"characteristics":[{"id":2,"name":"Quality of service min bandwidth","description":"Quality of service min bandwidth","minCardinality":null,"maxCardinality":null,"validFor":null,"values":[{"valueType":"FLOAT","defaultValue":false,"value":"60.0","valueFrom":null,"valueTo":null,"unitOfMeasure":"KBPS","validFor":null}],"valueType":"FLOAT","descriptorId":null}],"tags":null,"version":1,"sourceNetwork":"HPLMN","destinationNetwork":"*","descriptorId":null,"mobileNetworkOperator":{"id":1,"name":"TeliaSoneraSE","mobileCountryCode":"240","mobileNetworkCode":"01","issuerIdentificationNumber":"894601","country":{"name":"Sweden","code":"SE"}}}],"descriptorId":null},"lifecycleStatus":null,"mobileNetworkOperator":{"id":1,"name":"TeliaSoneraSE","mobileCountryCode":"240","mobileNetworkCode":"01","issuerIdentificationNumber":"894601","country":{"name":"Sweden","code":"SE"}},"tags":null,"descriptorId":null}],"lifecycleStatus":"active","tags":null,"descriptorId":null},"descriptorId":null,"tags":null,"productOfferingPrice":{"@class":"CompositeProductOfferingPrice","id":10,"description":"Composite product offering price for Joors subscription with Internet access","name":"Joors subscription with Internet access","validFor":null,"productSpecificationId":null,"productSpecificationCharacteristicValueUse":null,"resourceSpecificationCharacteristicValueUse":null,"serviceSpecificationCharacteristicValueUse":null,"productOfferingPrices":[{"@class":"AllowanceProductOfferingPriceAlteration","id":9,"description":"","name":"Allowance for Joors subscription with 150 MB data and 60 kbps access to any domain","validFor":{"startDateTime":1382514501068,"endDateTime":null},"productSpecificationId":4,"productSpecificationCharacteristicValueUse":null,"resourceSpecificationCharacteristicValueUse":null,"serviceSpecificationCharacteristicValueUse":{"productOfferingReference":{"id":8,"name":"Mobile subscription with Sim Card and Internet access 2GB","sortOrder":null},"productSpecificationReference":{"id":4,"name":"Mobile Internet access","sortOrder":null},"serviceSpecificationReference":{"id":3,"name":"Fallback Packet Data Access Service","sortOrder":null},"serviceSpecificationCharacteristicReference":{"id":2,"name":"Quality of service min bandwidth","sortOrder":null},"serviceSpecificationCharacteristicValueDto":{"valueType":"FLOAT","defaultValue":false,"value":"60.0","valueFrom":null,"valueTo":null,"unitOfMeasure":"KBPS","validFor":null}},"money":{"amount":0.00,"currency":"SEK"},"unitOfMeasure":null},{"@class":"AllowanceProductOfferingPriceAlteration","id":8,"description":"","name":"Allowance for Joors subscription with 2.0 GB data and 10.0 mbps access to any domain","validFor":{"startDateTime":1382514501068,"endDateTime":null},"productSpecificationId":4,"productSpecificationCharacteristicValueUse":null,"resourceSpecificationCharacteristicValueUse":null,"serviceSpecificationCharacteristicValueUse":{"productOfferingReference":{"id":8,"name":"Mobile subscription with Sim Card and Internet access 2GB","sortOrder":null},"productSpecificationReference":{"id":4,"name":"Mobile Internet access","sortOrder":null},"serviceSpecificationReference":{"id":2,"name":"Default Packet Data Access Service","sortOrder":null},"serviceSpecificationCharacteristicReference":{"id":1,"name":"Quality of service max bandwidth","sortOrder":null},"serviceSpecificationCharacteristicValueDto":{"valueType":"FLOAT","defaultValue":false,"value":"10.0","valueFrom":null,"valueTo":null,"unitOfMeasure":"MBPS","validFor":null}},"money":{"amount":0.00,"currency":"SEK"},"unitOfMeasure":null},{"@class":"AllowanceProductOfferingPriceAlteration","id":7,"description":"","name":"Allowance for Joors subscription with unlimited amount of data and access to joors.com and 10.0 mbps quality of service","validFor":{"startDateTime":1382514501068,"endDateTime":null},"productSpecificationId":4,"productSpecificationCharacteristicValueUse":null,"resourceSpecificationCharacteristicValueUse":null,"serviceSpecificationCharacteristicValueUse":{"productOfferingReference":{"id":8,"name":"Mobile subscription with Sim Card and Internet access 2GB","sortOrder":null},"productSpecificationReference":{"id":4,"name":"Mobile Internet access","sortOrder":null},"serviceSpecificationReference":{"id":1,"name":"Joors Domain Packet Data Access Service","sortOrder":null},"serviceSpecificationCharacteristicReference":{"id":1,"name":"Quality of service max bandwidth","sortOrder":null},"serviceSpecificationCharacteristicValueDto":{"valueType":"FLOAT","defaultValue":false,"value":"10.0","valueFrom":null,"valueTo":null,"unitOfMeasure":"MBPS","validFor":null}},"money":{"amount":0.00,"currency":"SEK"},"unitOfMeasure":null}]}}],"descriptorId":{"id":115},"tags":[{"name":"subscription","value":"free"}],"productOfferingPrice":null}]}

当我将上面的 JSON 放入 jsonviewer.stack.hu 时,它会正确渲染一个元素及其子元素,为什么 Sencha 不能做其他工具可以做的事情?

我已经简化了树应该呈现的 JSON,并且我已经检查它是否正确:

{
    "productOfferings": [
        {
            "name": "Mobile subscription with Internet access 2GB and iPad 32GB",
            "description": "Joors 2GB mobile broadband and iPad 32GB",
            "productOfferings": [
                {
                    "id": 5,
                    "name": "Ipad with 32 GB storage",
                    "description": "A iPad 32 GB Product Offering",
                    "productSpecification": {
                        "id": 5,
                        "name": "IPad",
                        "description": ""
                    }
                },
                {
                    "id": 8,
                    "name": "Mobile subscription with Sim Card and Internet access 2GB",
                    "description": "Mobile subscription with Sim Card and Internet access 2GB",
                    "productSpecification": {
                        "id": 9,
                        "name": "Mobile subscription with sim card and Internet access",
                        "description": "Mobile subscription with sim card and Internet access",
                        "productSpecifications": [
                            {
                                "id": 2,
                                "name": "Mobile subscription with Sim Card",
                                "description": "This is the classic Subscription product of a Mobile Network totally void of Services, so it can only be used for accessing a HPLMN. Simply put a MSISDN + SIM"
                            },
                            {
                                "id": 4,
                                "name": "Mobile Internet access",
                                "description": "This is a GPRS Service for a Mobile Network Access Product for accessing Internet"
                            }
                        ]
                    }
                }
            ]
        }
    ]
}

但是上面的内容对于 Sencha 来说仍然太复杂,无法用我的代码进行渲染。为什么这么难?这个小提琴说明了我的问题:http://jsfiddle.net/niklasro/auBTH/22/

【问题讨论】:

    标签: javascript json extjs


    【解决方案1】:

    你应该像这样定义你的树的叶子:

    {
        ... ,
        leaf: true
    
    }
    

    http://docs.sencha.com/extjs/4.2.1/#!/api/Ext.data.NodeInterface-cfg-leaf

    另外,为您的商店定义一个根

    Ext.define('MyApp.store.CheckNodes', {
    extend: 'Ext.data.TreeStore',
    
    requires: [
        'MyApp.model.CheckNode'
    ],
    
    constructor: function(cfg) {
        var me = this;
        cfg = cfg || {};
        me.callParent([Ext.apply({
            autoLoad: true,
            root: 'productOfferings',
            model: 'MyApp.model.CheckNode',
            storeId: 'CheckNodes',
            proxy: {
                type: 'ajax',
                root: 'productOfferings',
                url: 'data/tree.json'
            }
        }, cfg)]);
    }
    

    });

    【讨论】:

    • 当您在树中展开某些内容时,根属性会检查在何处查找更多数据。您应该查看this 问题以获取更多信息。和你遇到的问题一模一样,根据数据设置root解决了
    • 你小提琴里的那棵树有什么问题?看起来非常好...此外,对于如此复杂的 JSON,您最好使用仅返回所需元素的文件,例如在 this 示例中,get-nodes.php 仅从xml 文件
    • 我猜它无法渲染树,因为提供的 JSON 不正确,jsonviewer.stack.hu 也提醒我这是一个无效的 JSON 变量
    • 试图让小提琴工作,如果你删除 JSON 的最后一个 },它会显示树,但总的来说你是对的,ExtJS 不能真正让它按照你想要的方式工作。我想让它工作的唯一可能性是发送你正在扩展的 id 并相应地返回数据......
    • 正如我已经指出的那样,您应该尽量不要加载整个 JSON,而只加载扩展时需要的部分
    猜你喜欢
    • 2020-09-24
    • 2021-07-21
    • 2018-06-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多