在控制器中设置商店事件的侦听器

时间:2011-08-25 15:50:08

标签: javascript model-view-controller extjs extjs4

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

我需要在控制器中侦听商店的beforesyncwrite事件,但我不知道如何在控制器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
        }
    });
},
...

我的预期结果是在触发事件时将执行这些函数。 但此时他们被解雇时没有任何反应。

我怎样才能让它发挥作用?

8 个答案:

答案 0 :(得分:33)

{p> Your way是可能的,但它并不理想,IMO。更好的方法是使用控制器的商店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
    });
},

答案 1 :(得分:19)

以下是Molecular Man's answer的替代语法。

而不是写作,

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
    });
},

我认为这个替代定义会更好一些。

我从answer Izhaki给了我这个。

答案 2 :(得分:5)

对于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,
               ...

答案 3 :(得分:4)

Ext.define('Store', {
    model: 'Model',
    extend: 'Ext.data.Store',
    listeners: {
        'beforesync': function(){
            App.getController('somecontroller').onBeforeSync();
        }
    }
});

App - 您的应用程序对象 onBeforeSync函数可以在控制器中实现它...这是我可以将事件分配给存储并仍然在控件中实现逻辑的唯一方法。我希望它有所帮助

答案 4 :(得分:4)

我自己解决了。

我在我的Panel

render - 事件中手动添加了侦听器
Ext.getCmp('userPanel').down('gridpanel').getStore().addListener('write',this.finishedLoading, this);

感谢您的帮助@nscrob。

答案 5 :(得分:1)

希望这个新增功能可以帮助那些人避免花费一些时间来调试库核心:

与使用控制器的getter方法访问Controller内的Ext.data.Store实例的这种做法相关:例如对于上面的“DT.store.UsersStore”使用this.getUsersStoreStore():

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

stores: ['UsersStore']

实际上会在Ext.data.StoreManager.map hash中添加一个新的商店实例 - 假设'UsersStore'是迄今为止实例化的唯一Store对象 - 现在地图键看起来像:

0: "ext-empty-store"
1: "UsersStore"
2: "myStore"

现在假设您想使用store'proxy读取一些新数据并在“UsersGrid”中显示这些新数据,并且您希望在用户点击某些内容时执行所有这些操作,因此在控制器内部您将拥有一个处理程序方法带有代码的用户事件:

'user-selector' : {
    click: function(){
                     var oStoreReference = this.getUsersStoreStore();
                         oStoreReference.load( {params:{} });
            }
    }

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

因此,使用常规getStore方法更好地通过其itemId访问商店:this.getStore('storeItemId')

答案 6 :(得分:0)

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

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

然后能够

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

答案 7 :(得分:0)

以防万一有人绊倒这个。

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)
    }
});