Model view controller Extjs使用store创建动态手风琴

Model view controller Extjs使用store创建动态手风琴,model-view-controller,extjs,extjs4,accordion,store,Model View Controller,Extjs,Extjs4,Accordion,Store,我开始在extjs中开发一个应用程序。我使用的是MVC方法,如中提供的 我有一些动态数据,需要向用户提供一组手风琴控件。我在一个存储中获得了数据,但我不知道如何动态创建手风琴项目(与网格面板不同,似乎没有存储数据方法) 以下是我当前的手风琴视图代码-带有静态项: Ext.define('BP.view.induction.LeftPage', { extend: 'Ext.Panel', alias : 'widget.leftpage', title: "Left Page", layou

我开始在extjs中开发一个应用程序。我使用的是MVC方法,如中提供的

我有一些动态数据,需要向用户提供一组手风琴控件。我在一个存储中获得了数据,但我不知道如何动态创建手风琴项目(与网格面板不同,似乎没有存储数据方法)

以下是我当前的手风琴视图代码-带有静态项:

Ext.define('BP.view.induction.LeftPage', {
extend: 'Ext.Panel',
alias : 'widget.leftpage',

title: "Left Page", 
layout: {
    type: 'accordion',
    align: 'stretch'
},
layoutConfig: {
    // layout-specific configs go here
    titleCollapse: true,
    animate: true,
    activeOnTop: true
},
items: [{
    xtype: 'panel', // fake hidden panel, so all appear collapsed
    hidden: true,
    collapsed: false
},{
    xtype: 'panel',
    title: 'Panel 1',
    html: 'Panel content!'
},{
    xtype: 'panel',
    title: 'Panel 2',
    html: 'Panel content!'
},{
    xtype: 'panel',
    title: 'Panel 3',
    html: 'Panel content!'
}]
});
如有任何关于如何实现上述目标的指导,我们将不胜感激,谢谢

[编辑]根据sra的请求,以下是我的控制器:

Ext.define('BP.controller.Induction', {
extend: 'Ext.app.Controller',

views: [
    'induction.Binder'
],

stores: [
    'Sections',
    'Categories',
    'Tasks'
],

init: function() {
    console.log('Initialized Induction!');
}
});
这里我应该注意,这个控制器加载一个父视图,而父视图又加载LeftPage视图——我不确定这是否会产生任何范围问题。此外,如您所见,加载了多个存储。

您可以这样做(未经测试的示例中有一些调整)

您的店铺将至少需要两处房产;一个用于标题,一个用于内容。在实例化之前,需要加载存储。但这可以在控制器内轻松完成

根据评论和新的操作信息进行编辑:

你的视野有点失控了。因此,我建议您只需使用来接收有效实例(我编辑了代码,只是不知道要使用的正确存储)。只要你在控制器中列出店长,他就会知道商店的情况(店长有更多的能力,但这就是你目前需要知道的全部)。对于进一步的版本,您还可以使用mixin,它可以更干净地管理storebinding,并使您能够在商店收到新数据后更新手风琴(获得更新)

编辑以提高可读性


我刚刚对它进行了一些清理,并包括了一个开关param
attention
,它允许您将此组件直接绑定到存储,对所有加载事件作出反应,或者作为一种静态组件使用,其中存储应该已经加载。总而言之,这应该给你一个开始,而不会让它变得复杂。

感谢sra的帮助。我添加了代码并更改了此行:
me.sections.each(addItem)我在控制器中使用'stores'参数加载存储,但它告诉我它是未定义的。我相信这是很明显的,但作为一名extjs新手,我仍在为基础知识而挣扎。如果您能提供任何帮助,我们将不胜感激。@BrynJ好吧,我想从那以后,一切都会很顺利;使用
Ext.create('BP.view.inclution.LeftPage',{store:yourStoreVariable}创建
'BP.view.inclution.LeftPage'
的实例而不是
Ext.widget()
。如果这没有帮助,请删除实例化该类的控制器函数,我会看看我能做什么。我确信这是显而易见的,但对我来说不是:)我已将我的控制器代码添加到问题中,并在下面添加了一些详细信息。您还需要创建一个构造函数,将存储传递给您的对象。在调用buildContent之前,您需要确保您的存储已加载,最好是侦听存储的加载事件。initComponent将有类似的内容:me.store.on('load',function(){me.buildContent()});绝对地但这也可以由控制器完成。无论如何,我清理了我的例子。
Ext.define('BP.view.induction.LeftPage', {
    extend: 'Ext.Panel',
    alias : 'widget.leftpage',

    title: "Left Page", 
    layout: null,
    layoutConfig: null,
    store: null,
    attentive: true,
    initComponent: function() {
        var me = this;
        // begin edit
        // only set the store if is is not already defined
        me.store = me.store ? me.store : Ext.StoreMgr.lookup('Sections');  // you may change this to any storename you want
        // end edit
        me.layout = { // don't set objects directly in class definitions
            type: 'accordion',
            align: 'stretch'
        };
        me.layoutConfig = { // dont set objects directly in class definitions
            titleCollapse: true,
            animate: true,
            activeOnTop: true
        };

        me.callParent(arguments);
        if (me.attentive) {
            me.store('load', me.onRebuildContent, me);
            if (me.store.count() == 0)
                me.store.load();
        } else {
            me.buildContent(); 
        }
    },
    buildContent: function() {
        var me = this;
        function addItem(rec) {
            me.add({
                xtype: 'panel',
                title: rec.get('titleProperty'),
                html: rec.get('bodyProprty')
            });
        };

        me.store.each(addItem);
    },
    onRebuildContent: function() {
        var me = this;
        me.removeAll();
        me.buildContent();
    }   
});