Javascript 为控制器中的存储事件设置侦听器

Javascript 为控制器中的存储事件设置侦听器,javascript,model-view-controller,extjs,extjs4,Javascript,Model View Controller,Extjs,Extjs4,我有一个带有商店、模型和一些视图的控制器 我需要在控制器中侦听存储的beforesync和write事件,但我不知道如何在控制器control-功能中设置这些侦听器 我的商店看起来像这样: Ext.define('DT.store.UsersStore', { extend : 'Ext.data.Store', model : 'DT.model.User', id : 'myStore' autoSync : true, proxy : {

我有一个带有商店、模型和一些视图的控制器

我需要在控制器中侦听存储的
beforesync
write
事件,但我不知道如何在控制器
control
-功能中设置这些侦听器

我的商店看起来像这样:

Ext.define('DT.store.UsersStore', {
    extend : 'Ext.data.Store',
    model : 'DT.model.User',
    id : 'myStore'
    autoSync : true,
    proxy : {
        type : 'ajax',
        api : {
            read : '/load_entries',
            update : '/update_entry'
        },
        reader : {
            type : 'json',
            root : 'user',
            successProperty : 'success'
        }
    }
});
现在,我尝试收听控制器中的事件:

...
init : function () {
    this.control({
        'myStore' : {
            beforesync : this.doSomething,
            write : this.doSomethingElse
        }
    });
},
...
我的预期结果是,当触发事件时,将执行这些函数。 但在这个时候,当他们被解雇时,什么也没有发生

我怎样才能让它工作

Ext.define('Store', {
    model: 'Model',
    extend: 'Ext.data.Store',
    listeners: {
        'beforesync': function(){
            App.getController('somecontroller').onBeforeSync();
        }
    }
});
应用程序-您的应用程序对象 onBeforeSync函数可以在控制器中实现。。。这是我将事件分配给存储并仍然在控件中实现逻辑的唯一方法。我希望这有帮助

我自己解决了

我在面板的
render
-事件中手动添加了侦听器

Ext.getCmp('userPanel').down('gridpanel').getStore().addListener('write',this.finishedLoading, this);
感谢您的帮助@nscrob。

是可能的,但我认为这并不理想。更好的方法是使用控制器的存储getter。在您的情况下,代码如下所示:

init : function () {
    // every controller has getters for its stores.
    // For store UsersStore getter would be getUsersStoreStore()
    this.getUsersStoreStore().addListener('write',this.finishedLoading, this);
    this.control({
        // widgets event handlers
    });
},
stores: ['UsersStore']

下面是另一种语法

而不是写作

init : function () {
    this.getUsersStoreStore().addListener('write',this.finishedLoading, this);
    this.control({
        // widgets event handlers
    });
},
你可以写

init : function () {
    this.getUsersStoreStore().on({
        write: this.finishedLoading,
        scope: this
    });
    this.control({
        // widgets event handlers
    });
},
我认为这个替代定义读起来更好一点


这是我从一个给我的人那里得到的。

至于Extjs 4.2.1,如果您使用的是'storeId'而不是'id','listen'函数而不是'control',那么您最初访问存储侦听器的方法实际上是可行的:

Ext.define('DT.store.UsersStore', {
    extend : 'Ext.data.Store',
    model : 'DT.model.User',
    storeId : 'myStore'
    ....

init : function () {
    this.listen({
        store: {
           '#myStore' : {
               beforesync : this.doSomething,
               ...

为什么不直接转播商店的活动呢?例如:

this.getUsersGrid().relayEvents(this.getUsersStore(),['write'],'store')

然后才能

this.control('somegrid-selector':{storeWrite:function(){…})

希望此添加内容可以帮助其他人避免花费数小时调试库核心: 与使用控制器的getter方法访问控制器内Ext.data.Store实例的实践相关:例如,对于上面的“DT.Store.UsersStore”,使用this.getusersstore()

请注意,如果存储已经在视图中关联(例如,被声明为“UsersGrid”Grid.panel.panel小部件定义的存储属性),那么这个getter方法实际上将检索同一存储类的另一个实例,而不是小部件使用的实例 原因是在构造函数配置对象中添加存储,如下所示:

init : function () {
    // every controller has getters for its stores.
    // For store UsersStore getter would be getUsersStoreStore()
    this.getUsersStoreStore().addListener('write',this.finishedLoading, this);
    this.control({
        // widgets event handlers
    });
},
stores: ['UsersStore']
实际上,将在Ext.data.StoreManager.map散列中添加一个新的存储实例,因此-假设“UsersStore”是迄今为止唯一实例化的存储对象-映射键现在看起来像:

0: "ext-empty-store"
1: "UsersStore"
2: "myStore"
现在,假设您想使用商店的代理读取一些新数据,并在“UsersGrid”中显示这些新数据,并且您想在用户单击某个对象时执行所有这些操作,因此在控制器中,您将有一个用于用户事件的处理程序方法,代码如下:

'user-selector' : {
    click: function(){
                     var oStoreReference = this.getUsersStoreStore();
                         oStoreReference.load( {params:{} });
            }
    }
获取引用的调用将在这个.getStore('UsersStore')中进行内部转换,并将返回一个对控制器生成的引用-1:“UsersStore”-而不是预期的-2:“myStore”-。此外,load()调用将使用新模型加载UsersStore实例,这不会反映在网格视图中(因为网格已绑定并侦听“myStore”存储实例生成的事件)


因此,最好使用通用的getStore方法通过其itemId访问存储:this.getStore('storeItemId')

,以防有人在上面绊倒

ExtJS 7.3

Ext.define('DT.controller.UsersStore', {
    extend: 'Ext.app.Controller',

    listen: {
        store: {
            UsersStore: {
                beforesync : 'doSomething',
                write : 'doSomethingElse'
            }
        }
    },

    doSomething() {
        console.log(arguments)
    },

    doSomethingElse() {
        console.log(arguments)
    }
});

不,这不起作用。this.doSomething应该执行console.log('BeforeSync');但是仍然没有发生什么问题很明显,监听器没有将其分配给组件。您应该阅读extjs中的查询文档,该文档用于确定tu为哪个组件分配事件。尝试类似“widgetname gridPanel#store”(其中widgetname表示分配给控制器的视图)的方法。我现在没有什么东西要测试,但你应该一步一步地进行,首先在包含该存储的组件上添加一个事件,然后尝试在该存储上设置事件。哦。。。我发现store类既没有id也没有别名配置。我的配置将被忽略,并且不会在控制器中分配该项。还有别的办法吗?我在寻找替代方案,但没有找到。控制函数使用组件查询来获取组件,并存储它不是一个ext组件,它扩展了ext.base,因此我认为不可能使用组件查询来获取存储。我找到了另一个选择,我会用我找到的解决方案修改上面的答案。请不要将您的存储与控制器耦合,这是一个非常糟糕的主意,您不能在应用程序的其他部分重用此存储。甚至比我的解决方案更好。谢谢你,伙计。这个社区太棒了。这个解决方案是否可以在应用程序的某个部分使用您在其中定义的控制器时只执行代码就可以正常工作?或者从现在开始,这个事件会影响到这个新的侦听器吗?我想它只会在这个控制器内工作,但我不太清楚,因为我从来没有在一个应用程序中使用过多个控制器。在ST2.1 betaCan中似乎没有任何用于商店的getter,我们使用on()添加了多个侦听器?在本页的所有解决方案中,只有({..上的.getUsersStore()对我有效。(使用4.2.1)