在Ext JS 4 MVC应用程序中,应该负责加载商店?

Mit*_*hon 6 javascript model-view-controller extjs4 extjs-mvc

考虑一个复杂的应用程序,其中您有自定义过滤逻辑和不同的加载模式; 隐藏时延迟加载,隐藏时不加载,但在显示时加载并在修改自定义过滤器时重新加载等.

mvc app的哪个部分应该负责加载,以及如何连接它?

Aci*_*ier 15

当我开始使用MVC时,我从未在Sencha中找到明确的答案,但我可以告诉你我为一些应用成功做了些什么.

我根据它们的使用方式创建和加载我的商店.对我来说,这似乎分为三个不同的类别:

  1. 适用于整个应用的商店

  2. 适用于视图的所有实例的存储

  3. 绑定到单个视图实例的存储

1.适用于整个应用程序的商店

我通常有一个"主"控制器来处理我的应用程序的框架,如键盘导航,主菜单等.

属于上述第一类的商店将进入此"主"控制器stores阵列.如果这些商店不依赖于另一家商店,那么我只是制作它们autoLoad: true并完成它们.但是在它们依赖于另一个存储数据的情况下,我向父存储添加一个监听器以在父onLoad事件中加载依赖存储.

我发现属于第一类的一些商店的例子是我在整个应用程序中的组合框中使用的参考商店,通常在许多不同类型的视图中.这些通常配置,autoLoad: true然后我再也不会为该用户的会话加载它们.每当我需要一个使用引用存储的组合框时,我可以像这样设置它:

{
    xtype: 'combobox',
    allowBlank: false,
    forceSelection: true,
    store: Ext.getStore('SomeReferenceStore'),
    queryMode: 'local', // this makes sure the store doesn't reload
    valueField: 'id',
    displayField: 'name'
}
Run Code Online (Sandbox Code Playgroud)

举两个属于第一类的商店的例子,其中一个依赖于另一个:

在我的一个应用程序中,我拥有动态数量的用户权限,当用户登录应用程序时,我需要获取不同的权限并修改User模型以包含每个这些不同权限的布尔字段:

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

    models: [
        'User', 
        'Reference',
        // etc...
    ],

    stores: [
        'CurrentUser', 
        'PermissionRef', // this is "autoLoad: true"
        // etc...
    ],

    init: function() {
        var me = this;       

        // update the user model and load the user
        me.getPermissionRefStore().on('load', function(store, records) {
            var model = me.getUserModel(),
                fields = model.prototype.fields.getRange();

            // append the permissions onto the User model fields
            Ext.each(records, function(permission) {
                fields.push({
                    name: permission.get('name'), 
                    type: 'bool',
                });
            });

            // update the user model with the permission fields
            model.setFields(fields);

            // load the current user
            me.getCurrentUserStore().load();

            // other stuff...

        });

        // other stuff...

    }

});
Run Code Online (Sandbox Code Playgroud)

有了这个,每当我需要对用户的引用以及他可用的权限时,我只需调用:

var user = Ext.getStore('CurrentUser').first();
Run Code Online (Sandbox Code Playgroud)

有时视图也将依赖于正在加载的商店.例如,我的主菜单项由数据库表确定,在这种情况下,我将以onLoad相同的方式包含一个监听器(在控制器的init函数内):

// create the menu once we know what menu items are available
me.getMenuStore().on('load', function(store) {
    me.getViewport().add(Ext.widget('mainpanel'));            
});
Run Code Online (Sandbox Code Playgroud)

MyApp.store.Menu本身将与配置autoLoad: true.

2.适用于视图的所有实例的商店

我创建和加载这些就像第一类只有我把它们放在特定的视图控制器的stores数组而不是"主"控制器stores数组.

然后它是相同的基本概念,autoLoad: true如果它们依赖于另一个商店的数据,有些则不是.

对于那些不是autoLoad: true它们的人来说,它们被加载到控制器init函数内部或者某些事件被触发的结果.

3.绑定到单个视图实例的商店

在这里,我可能会反对MVC粒度,但实际上没有更好的地方适用于视图本身内部的视图的单个实例.

在大多数情况下,我甚至没有将这些商店放在视图控制器的stores数组中.我只是在视图的initComponent功能中创建并加载它们.因此,当视图被销毁时,不再有对商店的引用,因此商店也将被销毁.这有助于减少可能多次创建的商店的资源.

例如,假设你有一个MyApp.view.UnicornWeightGrid延伸a gridpanel并显示一个独角兽的渐进重量随着时间的推移.用户可以UnicornWeightGrid为领域中的所有独角兽打开一个用于比较和交叉引用的目的.会有的许多不同的情况下,UnicornWeightStore因为有的实例UnicornWeightGrid.

视图可以这样定义:

Ext.define('MyApp.view.UnicornWeightGrid', {
    extend: 'Ext.grid.Panel',
    alias: 'widget.unicornweight',
    requires: [
        'MyApp.model.UnicornWeight'
    ],
    closable: true,    
    initComponent: function() {
        var me = this;

        me.store = Ext.create('Ext.data.Store', {
            model: 'MyApp.model.UnicornWeight',
            proxy: {
                type: 'ajax',
                url: 'unicorns/weight',
                extraParams: {
                    name: me.unicornName
                }
            }
        });

        me.store.load();
    });
});
Run Code Online (Sandbox Code Playgroud)

然后,每当我们想要得到一个不同的,UnicornWeightGrid我们可以简单地调用

var grid = Ext.widget('unicornweight', {
    unicornName: someUnicornNameVariable
});

myTabPanel.add(grid);
Run Code Online (Sandbox Code Playgroud)

onLoad我在视图中定义的商店上需要的任何监听器,我也在视图中附加.所以我其他地方并不需要参考.

尽管如此,这绝不是建立商店的唯一方式.

我发现这是在创建一些不同的ExtJS"MVC"应用程序时始终如一地处理商店的最可行的方法,但我有时在"特殊"情况下也会采用不同的方式.

你应该记住,"MVC"是相当宽松的设计模式,它几乎在我使用过的每个框架中都有不同的定义和实现.所以你几乎可以做任何最适合你的事情.