我正在保存控件状态并将数据存储到数据库(目前仅是网格),并且我想知道在控件呈现/显示给用户时可以覆盖哪些侦听器或方法以将数据放回原位。

这是保存状态和存储数据的方法:

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。

免责声明:没有测试任何代码,所以我们希望它不会太遥远...

09-30 16:32
查看更多