[OPEN] [#164] Store save changed data in one request use store event

  1. #1

    [OPEN] [#164] Store save changed data in one request use store event

    Hi Everyone,

    I work with Ext.Net2.1, I just want to save store changed data in one request, I know I can do it use this https://examples2.ext.net/#/GridPanel/Update/Batch/ but I want an interface use Store event, so I check this https://examples2.ext.net/#/GridPane...s/StoreEvents/ and this https://examples2.ext.net/#/GridPane...reCustomLogic/ but when I invoke store.sync() on client side, it's call server side 3 times(create,update,destory).

    In summary, I need an event StoreSaveData with Store on server side, and a method save(options) with store on client side(or saveData,just a method name), when I call save(), I can set some options like skipIdForNewRecords,success,failure,etc, then StoreSaveData event fired, I can handle all create,update,destory data with StoreSaveDataEventArgs, I can get ChangeRecords<T> from it, or get JsonData etc. finally, the event can response changed data to client side and update client side store, or if there are exceptions, can give me a chance to handle it, that's all.

    Any suggestion?

    Thanks
    Last edited by Daniil; Mar 13, 2013 at 12:42 PM. Reason: [OPEN] [#164]
  2. #2
    Hi @devil,

    Maybe, it would be good to have, but there is no such functionality at the moment.

    Basing on the Batch example you mentioned you could organize a custom Store control which would behave as you need.

    I think there are the most of the things you need in that example.
  3. #3
    Hi Daniil,

    Thanks for you, I know the feature is not necessary for all users, but I really hope there is an official achieve.

    Any way, I try to add the feature by myself, I try three ways:

    (1)I try to override store.sync method in client side, I make an operations only have one operation, like this:
        sync: function(options) {
            var me = this,
                operations = {},
                toCreate = me.getNewRecords(),
                toUpdate = me.getUpdatedRecords(),
                toDestroy = me.getRemovedRecords(),
                needsSync = false;
    
            if (toCreate.length > 0) {
                if (options.useSave) {
                    if (!operations.save) operations.save = {};
                    operations.save.Created = toCreate;
                } else
                    operations.create = toCreate;
                needsSync = true;
            }
    
            if (toUpdate.length > 0) {
                if (options.useSave) {
                    if (!operations.save) operations.save = {};
                    operations.save.Updated = toUpdate;
                } else
                    operations.update = toUpdate;
                needsSync = true;
            }
    
            if (toDestroy.length > 0) {
                if (options.useSave) {
                    if (!operations.save) operations.save = {};
                    operations.save.Deleted = toDestroy;
                } else
                    operations.destroy = toDestroy;
                needsSync = true;
            }
    
            if (needsSync && me.fireEvent('beforesync', operations) !== false) {
                options = options || {};
    
                me.proxy.batch(Ext.apply(options, {
                    operations: operations,
                    listeners: me.getBatchListeners()
                }));
            }
            
            return me;
        }
    and I add some other code, make it run, on client side, I can call store.sync({useSave:true}) to fire server side event, on server side, I add SaveDataEvent for Store,and add StoreAction.Save for StoreAction enum and many other code, but when I try to add code to support save action, I find the privite method DoSaving in Store.cs need to do a big change, so I give up this way. I think it's not a good way.

    (2)I find store.submitData method and SubmitData Event, I think I can make saveData method and SaveData Event, then I add code for store like this:
        saveData: function (options, requestConfig) {
            this._save(null, options, requestConfig);
        },
    
        _save: function (data, options, requestConfig) {
            if (!data) {
                data = this.getChangedData(options);
            }
    
            options = { params: (options && options.params) ? options.params : {} };
            
            if (Ext.isString(requestConfig)) {
                requestConfig = {
                    url: requestConfig
                };
            }
    
            var config = {},
                ac = requestConfig || {},
                isClean = !!ac.url;
    
            ac.userSuccess = ac.success;
            ac.userFailure = ac.failure;
            delete ac.success;
            delete ac.failure;
            ac.extraParams = options.params;
            ac.enforceFailureWarning = !ac.userFailure;
    
            if (isClean) {
                ac.cleanRequest = true;
                ac.extraParams = ac.extraParams || {};
                ac.extraParams.data = data;
            }
    
            Ext.apply(config, ac, {
                control: this,
                eventType: "postback",
                action: "save",
                serviceParams: data
            });
    
            Ext.net.DirectEvent.request(config);
        }
    and this:

        case "save":
            if (data == null)
            {
                throw new InvalidOperationException("No data in request");
            }
            StoreSaveDataEventArgs arg = new StoreSaveDataEventArgs(data, parametersToken);
            this.OnSaveData(arg);
    I success, I can use StoreSaveDataEventArgs get changed data
        protected void Store1_SaveData(object sender, StoreSaveDataEventArgs e)
        {
            var datas = e.BatchObjectData<Model>();
            foreach (var model in datas.Created)
            {
                //do insert...
            }
        }
    (3)But I can't sync changes to client side store like sync, I must make it myself. so I change server code to this:
        case "save":
            if (data == null)
            {
                throw new InvalidOperationException("No data in request");
            }
            //StoreSaveDataEventArgs arg = new StoreSaveDataEventArgs(data, parametersToken);
            //this.OnSaveData(arg);
            var handler = new StoreDataHandler(data);
            var jobj = JObject.Parse(data);
            var created = (JArray)jobj["Created"];
            var updated = (JArray)jobj["Updated"];
            var deleted = (JArray)jobj["Deleted"];
            if (created != null) this.DoSaving("create", created.ToString(), parametersToken);
            if (updated != null) this.DoSaving("update", updated.ToString(), parametersToken);
            if (deleted != null) this.DoSaving("destory", deleted.ToString(), parametersToken);
            break;
    I want use DoSaving to save data and make it auto sync, but it don't sync to client side, I review the code, I know I must use callback write data to store, but I find it complex for me. so if you feel valuable to users, I hope offical version can add this feature.

    btw:I create a patch for this, but I can't upload it with extension .patch,so I change extension to .txt.StoreSavedDataEvent.patch.txt
  4. #4
    We created an Issue with your feature request. Though, no time frame and even no guarantee it will be implement. But, certainly, it is possible
    https://github.com/extnet/Ext.NET/issues/164

    I looked at your attempts to implement it.

    Please clarify why do not you want to use this example as a base?
    https://examples2.ext.net/#/GridPanel/Update/Batch/
  5. #5
    Hi Daniil,

    Thank you. now I try to explain to you why I want the feature.

    We are working with Ext.Net2.1, and I know it provide powerful function for us, but in our internal framework, we only use part of the function, for example, we only use PageProxy for Store in our internal framework, so we are more dependent on StoreEvents, and I also found that the StoreEvents can auto sync to client store, but not in one request. we try to encapsulation Ext.Net for our internal framework to make it more simple, so I need a StoreSaveEvent.

    At first, we have been used inherit to add some feature for Store(eg:I've added a feature for Store, make it load first page data when page load), so I try to override base Store functions to achieve it, but I found I can't unless modify source code, we do not want to modify the source code, so we want the official to achieve. that's all.

    I am very aware that the feature is not required nor is everyone needs, so if you do not to achieve it and I understand very well. anyway, thanks for everyone.
  6. #6
    Thank you for the details.

    You could extend your custom Store C# class with a new DirectEvent, like BatchSaved.

    When extend a JavaScript Store class with a new method like syncBatch where you can use the getChangedData
    #{Store1}.getChangedData({skipIdForNewRecords : false})
    and fire a BatchSaved event.
  7. #7
    But how to sync to client store when I saved changed data on server side?
  8. #8
    It is demonstrated in the example, isn't?
  9. #9
    I hope it can auto sync, anyway, I will try to add a DirectEvent by myself, thanks.

Similar Threads

  1. Replies: 4
    Last Post: Oct 19, 2012, 6:14 PM
  2. Store callback twice on data request
    By yossi in forum 1.x Help
    Replies: 1
    Last Post: Jun 06, 2012, 2:55 PM
  3. Replies: 12
    Last Post: Feb 20, 2012, 1:58 PM
  4. Error for Update Changed data
    By dicklee2003 in forum Open Discussions
    Replies: 0
    Last Post: Dec 03, 2009, 3:03 PM
  5. Data back on a Store.save()
    By Dave.Sanders in forum 1.x Legacy Premium Help
    Replies: 2
    Last Post: Sep 03, 2008, 1:03 PM

Tags for this Thread

Posting Permissions