困扰于roload参数不变的问题,很幸运在网上找到了答案,贴在下面:
http://www.javaeye.com/topic/713163
ExtJs 中,我们使用GirdPanel的时候往往需要给后台传递查询条件。
一般是通过修改Store的baseParams。
- var store = GirdPanel.getStore();
- store.baseParams = { 查询条件 }
- store.reload(); //刷新表格
这个方法在ExtJs 2.x 和 ExtJS 3.0.0 中都使用。
但是当使用ExtJS 3.1.0的时候,问题就出现了。
我们会发现无论如何修改baseParams,查询条件依然还是第一次修改baseParams时候的条件。
所以我们无法通过修改baseParams 来满足修改查询条件的目的。
于是我们观察ExtJS 3.1.0源码发现
- reload : function(options){
- this.load(Ext.applyIf(options||{}, this.lastOptions));
- }
这里我们要说一下lastOptions的作用。
lastOptions用于保留最后一次的查询配置信息。
我们再去跟踪其他部分的代码。
这个是load的时候的代码。
我们可以看到首先使用storeOptions 方法保存了最后一次的查询条件。然后在调用execute执行查询。
- load : function(options) {
- options = options || {};
- this.storeOptions(options);
- if(this.sortInfo && this.remoteSort){
- var pn = this.paramNames;
- options.params = options.params || {};
- options.params[pn.sort] = this.sortInfo.field;
- options.params[pn.dir] = this.sortInfo.direction;
- }
- try {
- return this.execute('read', null, options); // <-- null represents rs. No rs for load actions.
- } catch(e) {
- this.handleException(e);
- return false;
- }
- },
- storeOptions : function(o){
- o = Ext.apply({}, o);
- delete o.callback;
- delete o.scope;
- this.lastOptions = o;
- },
- execute : function(action, rs, options, /* private */ batch) {
- if (!Ext.data.Api.isAction(action)) {
- throw new Ext.data.Api.Error('execute', action);
- }
- options = Ext.applyIf(options||{}, {
- params: {}
- });
- if(batch !== undefined){
- this.addToBatch(batch);
- }
- var doRequest = true;
- if (action === 'read') {
- Ext.applyIf(options.params, this.baseParams);
- doRequest = this.fireEvent('beforeload', this, options);
- }
- else {
- if (this.writer.listful === true && this.restful !== true) {
- rs = (Ext.isArray(rs)) ? rs : [rs];
- }
- else if (Ext.isArray(rs) && rs.length == 1) {
- rs = rs.shift();
- }
- if ((doRequest = this.fireEvent('beforewrite', this, action, rs, options)) !== false) {
- this.writer.apply(options.params, this.baseParams, action, rs);
- }
- }
- if (doRequest !== false) { if (this.writer && this.proxy.url && !this.proxy.restful && !Ext.data.Api.hasUniqueUrl(this.proxy, action)) {
- options.params.xaction = action; }
- this.proxy.request(Ext.data.Api.actions[action], rs, options.params, this.reader, this.createCallback(action, rs, batch), this, options);
- }
- return doRequest;
- },
我们重点关注
storeOptions 方法中的 o = Ext.apply({}, o);
和
execute 的 Ext.applyIf(options.params, this.baseParams);
他的目的是这样的。
首先
[storeOptions ]
克隆一个新的 Options ,并保存到lastOptions中。
lastOptions使用新的Options的目的是原有Options发生变化lastOptions不变。
[execute ]
然后将baseParams的内容添加到Options.params中,并使用Options.params作为参数进行查询。
逻辑上没有错误
是将baseParams内容添加到原有的Options.params中。
新的lastOptions(Options2)内容不变。(因为是克隆的)
但是实际上Options.params发生变化的而同时。lastOptions中的params也发生了变化。
原因在storeOptions 方法上。
o = Ext.apply({}, o);
做的只是一个浅层拷贝。拷贝之后
lastOptions.params 和 Options.params 其实是一个对象。
所以当Options.params发生变化lastOptions.params也发生变化。
(不知道是Jack Slocum故意这么设计的还是没有考虑周全,不过这造成了版本的不兼容)
原因找到了,修改起来也就容易了。我们只需要重构storeOptions 方法,将其params也拷贝一次就可以了。
- Ext.override(Ext.data.Store, {
- storeOptions : function(o) {
- o = Ext.apply({}, o);
- if(o.params)
- o.params = Ext.apply({}, o.params);
- }
- delete o.callback;
- delete o.scope;
- this.lastOptions = o;
- }
- });