Extjs - autoload属性设置为true的Store不应在应用程序启动时加载

8
我有一个与存储器链接的网格,其 autoLoad: true。问题是存储器在应用程序启动时加载,即使只有通过菜单访问时才创建视图。
我已经在 Application.js 和视图中引用了存储器,但我既没有显式地实例化存储器也没有实例化视图。
我不知道如何实现仅在视图需要时加载存储器。
  • 如果设置了 autoLoad: true,则存储器将在应用程序启动时加载。
  • 如果设置了 autoLoad: false,则根本不会加载存储器。
我知道这很基础,但我到目前为止卡住了。
以下是所有相关代码以供参考:
app/store/Owners.js
Ext.define('Mb.store.Owners', {
    extend: 'Ext.data.Store',
    model: 'Mb.model.Owner',
    autoLoad: true,
    proxy: {
        ...
});

Application.js

Ext.define('Mb.Application', {
    name: 'Mb',
    extend: 'Ext.app.Application',
    models: [
        'Owner'
    ],
    stores: [
        'Owners'
    ],
    ...

app/view/Owners.js

Ext.define('Mb.view.winbiz.Owners', {
    extend: 'Ext.grid.Panel',
    alias: 'widget.test-gridPanel',
    store: 'winbiz.Owners',
    columns: [{
    ...

视图在控制器中实例化:
Ext.define('Mb.controller.Winbiz', {
    extend: 'Ext.app.Controller',
    views: [
        'Owners'
    ],
    init: function(){
        this.control({
            'menu #test': {click: this.onMenuTest},
        })
    },
    onMenuTest: function(){
        this.getController('Main').addToMainTab('test-gridPanel');
    },
3个回答

8
您可以在视图中添加render处理程序,该处理程序将调用存储load方法并禁用autoLoad

示例监听器:

Ext.define('Mb.view.winbiz.Owners', {
    extend: 'Ext.grid.Panel',
    [...],

    initComponent: function(){
        this.callParent();
        this.on('render', this.loadStore, this);
    },

    loadStore: function() {
        this.getStore().load();
    }
});

4
我不喜欢在视图中编写代码。如果你在视图中写应该由控制器负责的代码,那么使用控制器就没有意义。这种解决方案还会在每次渲染视图时重新加载存储——可能是不必要的? - oldwizard

1
我会让视图控制器处理存储加载。
首先,在存储上禁用自动加载。
Ext.define('Mb.controller.Winbiz', {
    extend: 'Ext.app.Controller',
    views: [
        'Owners'
    ],
    ownerStore: null,
    init: function(){
        this.control({
            'menu #test': {click: this.onMenuTest},
        });

        this.ownerStore = Ext.getStore('winbiz.Owners');
    },
    onMenuTest: function() {
        if (this.ownerStore.loaded === false) {
            this.ownerStore.load(
                scope: this,
                callback: this.onOwnerStoreLoaded
            );
        }
        else {
            this.addToTab();
        }            
    },
    onOwnerStoreLoaded: function (store, records, successful, eOpts) {
        if (successful) {
            store.loaded = true;
            this.addToTab();
        }
    },
    addToTab: function () {
        this.getController('Main').addToMainTab('test-gridPanel');
    }

无论您想在存储加载之前还是之后更改视图都是另一个问题。

你说得对,代码应该放在控制器中,而不应该重新加载存储。你的代码有点冗长,我会尝试让它更短。 - Lorenz Meyer

0

这是我的最终控制器代码:

Ext.define('Mb.controller.Winbiz', {
    extend: 'Ext.app.Controller',
    views: [
        'Owners'
    ],
    refs: [{ref: 'testGrid', selector: 'test-gridPanel'}],
    init: function(){
        this.listen({
            store: {
                '#Owners':{ load: this.onOwnersLoad}
            }
        })
        this.control({
            'menu #test': {click: this.onMenuTest},
            'test-gridPanel': {render: this.onOwnersRender}
        })
    },
    onMenuTest: function(){
        this.getController('Main').addToMainTab('test-gridPanel');
    },
    onOwnersLoad: function(store){
        store.loaded = true
    },
    onOwnersRender: function(){
        var store = this.getTestGrid().getStore();
        if(!store.loaded)store.load();
    },

根据@pcguru的建议,它将所有代码放在控制器中,并使用render事件来缩短代码,正如@Lolo所建议的那样。谢谢


你的代码中没有设置.loaded,它将始终加载存储。 - oldwizard
@pcguru 你说得对。这意味着除非在存储加载时将其存储在变量中,否则无法知道存储是否已加载? - Lorenz Meyer
1
@pcguru,我更新了我的代码以解决这个问题。现在它不再比你的短了 :( - Lorenz Meyer
:) 但是如果代码能够正确运行、更具可重用性和效率,并且比较易于阅读和理解,那么长一点的代码就更好了,我个人认为。有人可能会认为“loaded”应该是一个内置功能。但是,如果您愿意,可以轻松地为Ext.data.Store创建一个覆盖 - 这样您就不必为每个存储器重复此操作 - 如果这样做,您可以从此控制器中删除已加载的部分。 - oldwizard

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接