如何在Sencha中呈现嵌套的JSON?

时间:2013-10-24 06:50:45

标签: javascript json extjs

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

enter image description here

现在我想使用Sencha ExtJS做类似的事情,但是较低级别不会渲染:

enter image description here

即使我将所有节点重命名为名称“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不能做其他工具可以做的事情?

enter image description here

我已经简化了树应该渲染的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/

1 个答案:

答案 0 :(得分: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)]);
}

});