我正在保存控件状态并将数据存储到数据库(目前仅是网格),并且我想知道在控件呈现/显示给用户时可以覆盖哪些侦听器或方法以将数据放回原位。
这是保存状态和存储数据的方法:
SaveControlState: function (controlItemId, controlType, active, successFunction, scope) {
//Save the control state and its data to server...
var controlState = {};
var control = this.getCmp(controlType + '[itemId=' + controlItemId + ']');
controlState.ControlItemId = control.itemId;
controlState.ControlState = Ext.JSON.encode(control.getState()); //save a JSON string to database...
//if the control has this attribute, it means it wants to update its control state/data...
if (typeof control.controlStateId != 'undefined') controlState.ID = control.controlStateId;
controlState.Active = active;
//if control has a store, let's send data over server...
if (control.getStore() != null) {
controlState.ControlStoreData = [];
Ext.each(control.getStore().data.items, function (record) {
controlState.ControlStoreData.push(record.data);
});
controlState.ControlStoreData = Ext.JSON.encode(controlState.ControlStoreData); //same here...
}
control.setLoading({ msg: Strings.Messages.str_Wait });
//initiate request...
Ext.Ajax.request(
{
url: GlobalVars.Urls.portalControlStateCreateApiUrl,
params: { jsonData: Ext.JSON.encode(controlState), action: 'createcontrolstate' },
method: 'POST',
success: function (result, request) {
//hide spinner...
this.getCmp(controlType + '[itemId=' + controlItemId + ']').setLoading(false);
//if we had a success handler provided, call it...
if (typeof successFunction != 'undefined') successFunction(scope);
},
failure: function (result, request) {
var control = this.getCmp(controlType + '[itemId=' + controlItemId + ']');
control.setLoading(false);
Ext.Msg.show({
title: Strings.UI.str_Error,
msg: Strings.format(Strings.UI.Messages.str_ErrorControlState, control.id, result.responseText),
buttons: Ext.MessageBox.OK,
icon: Ext.MessageBox.ERROR
});
},
scope: this
});
}
当用户登录时,我正在检索所有活动控件状态条目:
Ext.create('App.store.ControlState', {
autoLoad: true,
scope: this,
storeId: 'controlStateStore',
proxy: {
type: 'ajax',
extraParams: { activeOnly: true },
url: GlobalVars.Urls.portalControlStateGetAllApiUrl,
headers: { 'Content-type': 'application/json' },
reader: { type: 'json', root: 'ControlStates' }
},
listeners: { load: function (store, records, success, opts) {
//one this is done, I show the rest of the UI....
}
}
});
现在我需要的是一个覆盖,如果我有匹配项(使用控件的
itemId
属性),则允许我窥视上面的存储并找到一条记录,然后应用状态并将数据加载到存储中(如果该控件存在)被覆盖的确有商店。有什么想法可以用吗?谢谢。
最佳答案
实现Stateful
的控件已经可以完全使用applyState()
和getState()
功能来保存/恢复状态。因此,每当必须更改/应用控制状态时,就会调用这些函数。我认为,如果您重用Stateful,ExtJS将为您处理其他所有事情(如果网格过滤器已更改等,则重新加载商店等)。
但是我不认为您可以做一个覆盖来使状态在每个组件中都能工作,因为每种组件类型都需要一个特定的状态列表。 ExtJS没有提供这样的列表。甚至没有标准组件。
因此,我担心您将不得不对每种组件类型进行一次覆盖。
如果我是你,我将创建一个ID为controlStateStore且具有三个半字段模型的商店:
itemId // type string
propertyName // type string
propertyValue // no type(!)
id // auto-created using `convert` to concatenate itemId, a comma and propertyName.
此存储将获得两个增值函数,以将
Stateful
状态对象加载/存储到模型中:getState:function(itemId) {
var records = store.Query("itemId",itemId);
var state = {};
records.each(function rec() {
state[rec.get("propertyName")]=rec.get("propertyValue");
})
return state;
}
setState:function(itemId,state) {
// add one record to the store per property
for(k in state) {
store.add({itemId:itemId,propertyName:k,propertyValue:state[k]});
}
// idProperty id will take care of replacing duplicates
}
这些是商店中的功能。现在,在每种组件类型上,您将需要一个实现Stateful的重写。因此,让我们看一下“推荐的” getState / applyState函数,该函数可能类似于以下内容:
xtype:button,
stateful:true,
stateid:'bla',
getState:function() {
// required if you want to save state
// by default, getState is empty function, so nothing is saved
return {pressed:this.pressed}; // here, a bigger object would be returned
// depending on the component type
},
applyState: function(state) {
// not required, since this function already exists and is the same for alle component types.
if (state) {
Ext.apply(this, state);
}
},
在这里,我将两者都替换为sth。喜欢:
getState:function() {
if(this.itemId)
Ext.getStore("controlStateStore").setState(this.itemId,{pressed:this.pressed})
},
applyState: function() {
if(this.itemId) {
var state = Ext.getStore("controlStateStore").getState(this.itemId);
Ext.apply(this, state);
}
},
并向两者都添加store.sync(),或者更好的方法是在商店上使用autoSync。
尽管我选择使用stateId而不是itemId使其保持兼容。由于可以重用ItemId,但是您不希望组件采用其他组件的状态(具有相同的itemId),因此应考虑使用id或stateId,而不是itemId。
免责声明:没有测试任何代码,所以我们希望它不会太遥远...