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

标签 javascript model-view-controller extjs4 extjs-mvc

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

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

最佳答案

当我开始使用 MVC 时,我从未从 Sencha 那里找到明确的答案,但我可以告诉你我成功地为一些应用程序做了什么。

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

  • 适用于整个应用程序的商店
  • 适用于 View 所有实例的存储
  • 绑定(bind)到单个 View 实例的存储

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

    我通常有一个“主” Controller 来处理我的应用程序的框架,比如键盘导航、主菜单等。

    属于上述第一类的商店进入此“主” Controller 的 stores大批。如果这些商店不依赖于另一家商店,那么我只是让它们autoLoad: true和他们做完了。但是在它们依赖于另一个存储数据的情况下,然后我向父存储添加一个监听器以加载父存储中的依赖存储 onLoad事件。

    我发现属于第一类的一些商店的一个例子是我在整个应用程序的组合框中使用的引用商店,通常在许多不同类型的 View 中。这些通常配置为 autoLoad: true然后我再也没有为该用户的 session 加载它们。每当我需要一个使用引用存储的组合框时,我都可以这样设置:
    {
        xtype: 'combobox',
        allowBlank: false,
        forceSelection: true,
        store: Ext.getStore('SomeReferenceStore'),
        queryMode: 'local', // this makes sure the store doesn't reload
        valueField: 'id',
        displayField: 'name'
    }
    

    举一个两个商店的例子,它们都属于第一类,一个依赖于另一个:

    在我的一个应用程序中,我拥有动态数量的用户权限,当用户登录该应用程序时,我需要获取不同的权限并修改 User模型为每个不同的权限包含一个 bool 字段:
    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...
    
        }
    
    });
    

    有了这个,每当我需要对用户的引用以及他有哪些可用权限时,我只需调用:
    var user = Ext.getStore('CurrentUser').first();
    

    有时 View 也将依赖于正在加载的商店。例如,我的主菜单项由数据库表确定,在这种情况下,我将包含一个 onLoad以同样的方式监听(在 Controller 的 init 函数中):
    // create the menu once we know what menu items are available
    me.getMenuStore().on('load', function(store) {
        me.getViewport().add(Ext.widget('mainpanel'));            
    });
    
    MyApp.store.Menu本身将配置为 autoLoad: true .

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

    我创建和加载这些就像第一类一样,只是我将它们放在特定 View Controller 的 stores 中。数组而不是“主” Controller stores大批。

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

    对于那些不是 autoLoad: true它们被加载到 Controller init 内的某处函数或作为某些事件被触发的结果。

    3. 绑定(bind)到单个 View 实例的存储

    在这里,我可能会反对 MVC 模式,但是对于应用到 View 的单个实例然后在 View 本身内部应用的存储来说,真的没有比这更好的地方了。

    在大多数情况下,我什至不会将这些存储放在 View Controller 的 stores 中。大批。我只是在 View 的 initComponent 中创建并加载它们功能。因此,当 View 被销毁时,不再有对商店的引用,因此商店也将被销毁。这有助于减少可以多次创建的商店的资源。

    例如,假设您有一个 MyApp.view.UnicornWeightGrid扩展 gridpanel并显示随着时间的推移独 Angular 兽的渐进权重。用户可以打开 UnicornWeightGrid对于该领域中的所有独 Angular 兽,用于比较和交叉引用。 UnicornWeightStore 将有许多不同的实例。因为有 UnicornWeightGrid 的实例.

    View 可以这样定义:
    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();
        });
    });
    

    然后每当我们想要获得不同的 UnicornWeightGrid我们可以简单地调用:
    var grid = Ext.widget('unicornweight', {
        unicornName: someUnicornNameVariable
    });
    
    myTabPanel.add(grid);
    

    任意 onLoad我在 View 中定义的商店上需要的监听器,我也附加在 View 内。所以我真的不需要其他任何地方的引用。

    尽管如此,这绝不是设置商店的唯一方法。

    我发现这是在创建几个不同的 ExtJS“MVC”应用程序时始终如一地处理存储的最可行的方法,但有时我在“特殊”情况下也会以不同的方式执行此操作。

    您应该记住,“MVC”是一种非常松散的设计模式,它在我使用过的几乎每个框架中的定义和实现方式都不同。所以你几乎可以做任何最适合你的事情。

    关于javascript - 在 Ext JS 4 MVC 应用程序中,什么应该负责加载商店?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12106055/

    相关文章:

    extjs - 如何在一个请求中加载 TreePanel 中的所有节点(及其子节点)?

    javascript - angularjs:在模板之外获取路由解析数据

    php - Laravel 5.2 查询在本地主机上正常工作,而不是在远程服务器上

    c# - 在 select 语句中从 IEnumerable 转换为 Queryable?

    php - 使用 PHP 自定义 MVC 将参数传递给方法

    javascript - Extjs 4如何在商店窗口网格中显示所选行

    javascript - ExtJs添加新记录时删除现有记录

    javascript - setAttribute 的替代品

    javascript - 平滑滚动仅适用于同一页面,不适用于外部链接

    javascript - extjs 中的 refs 是被覆盖还是被继承?