ExtJS 5.0.1中能否在Store内使用自定义变量?
解决ExtJS 5.0.1中Store内部自定义变量无法通过
this访问的问题 核心原因
在Ext.define定义类的配置对象中,proxy的配置是在类定义阶段执行的,此时this并不指向Store的实例,而是当前代码的全局/局部作用域,所以直接用this.myControllerPath会取不到值。
方案1:通过initComponent初始化Proxy
利用组件的initComponent生命周期方法,在实例化阶段动态构建proxy,此时this可以正常访问类的自定义属性:
Ext.define("xxx.store.foo.bar.myStore", { extend: "Ext.data.Store", model: "xxx.model.foo.bar.myModel", // 自定义controller路径 myControllerPath: "this/is/my/path/to/my/controller", autoLoad: false, initComponent: function() { // 动态构建proxy this.proxy = { type: "ajax", timeout: 20000, api: { read: this.myControllerPath + "?data=read", create: this.myControllerPath + "?data=create", update: this.myControllerPath + "?data=update", destroy: this.myControllerPath + "?data=delete", }, reader: { type: "json", rootProperty: "data", idProperty: "id", totalProperty: "total", }, writer: { type: "json", encode: true, writeAllFields: true, rootProperty: "data", idProperty: "id", }, }; // 调用父类的initComponent完成初始化 this.callParent(arguments); } });
方案2:创建可复用的基类Store(推荐)
既然需要频繁创建Store,最合理的方式是封装一个通用基类,子类只需要配置必要的属性(如controller路径、model)即可:
// 定义基类Store Ext.define("xxx.store.BaseStore", { extend: "Ext.data.Store", // 子类必须覆盖的属性 myControllerPath: "", model: "", autoLoad: false, initComponent: function() { // 校验必填属性 if (!this.myControllerPath) { Ext.Error.raise("必须配置myControllerPath属性"); } if (!this.model) { Ext.Error.raise("必须配置model属性"); } this.proxy = { type: "ajax", timeout: 20000, api: { read: this.myControllerPath + "?data=read", create: this.myControllerPath + "?data=create", update: this.myControllerPath + "?data=update", destroy: this.myControllerPath + "?data=delete", }, reader: { type: "json", rootProperty: "data", idProperty: "id", totalProperty: "total", }, writer: { type: "json", encode: true, writeAllFields: true, rootProperty: "data", idProperty: "id", }, }; this.callParent(arguments); } }); // 子类继承基类,只需配置少量属性 Ext.define("xxx.store.foo.bar.myStore", { extend: "xxx.store.BaseStore", model: "xxx.model.foo.bar.myModel", myControllerPath: "this/is/my/path/to/my/controller" });
方案3:使用config配置项(ExtJS 5支持)
将自定义属性声明为config,ExtJS会自动生成对应的getter方法,然后在initComponent中使用getter访问:
Ext.define("xxx.store.foo.bar.myStore", { extend: "Ext.data.Store", model: "xxx.model.foo.bar.myModel", autoLoad: false, // 声明config config: { myControllerPath: "this/is/my/path/to/my/controller" }, initComponent: function() { this.proxy = { type: "ajax", timeout: 20000, api: { read: this.getMyControllerPath() + "?data=read", create: this.getMyControllerPath() + "?data=create", update: this.getMyControllerPath() + "?data=update", destroy: this.getMyControllerPath() + "?data=delete", }, // reader和writer配置同前 }; this.callParent(arguments); } });
关于之前外部变量的问题
你之前用const报错,是因为const声明的变量是块级作用域,当多个Store共享时可能出现作用域冲突;而let虽然解决了部分问题,但全局/局部变量的方式不利于代码封装和维护,上面的方案都能避免这种问题。
内容的提问来源于stack exchange,提问作者Dwza
相关产品推荐
相关产品推荐

