9
votes

I have a problem that's bugging me.

I have a grid and when i dblclick on a item I want to open a window to edit that item. Pretty standard stuff. The problem is, i want to be sure the record is up to date, because other people using the program may have changed it or even deleted it.

I could reload the store, but i only want one specific record to be checked... So i figured i would just go get the data, build another record and replace the existing one in the store but i really want to know the best way to do this

Bear in mind RESTful proxy is not an option for me, even though i don't know if the update operation works in this case ( server -> client).

EDIT: this may help somebody: all i did was copy the data and raw objects from the new record to the old one and then "commit" the changes. worked for me.

Thank you.

4

4 Answers

4
votes

The best way to do something like this would be to reload the record in the event which opens the window. So where you would for example load the record from the grid store into a form within the window, you can use your model to load from the id.

Item.load(id, { success: function(r) { form.loadRecord(r); } });

Once saved, you should probably also call refresh on the grid view, which will redraw the changes from the save event. You can also use refreshNode (see grid view documentation) on the exact record in the store if you're concerned about performance.

Of course you do not have to use the restful proxy with this, you can use any proxy as long as it will load the single record.

5
votes

ExtJS 4.1

I had a similar problem and as an experiment tried

sStore.load({ id: mskey, addRecords: true });

where mskey is a uuid of a currently loaded record.

I did not remove the existing record first (as an experiment) and it updated the existing record that had the same id with the new data from the server (via the model --> REST proxy). Perfect!

I know you said you are not using a REST proxy, but this might help others who found this post searching for search terms like your topic name (which is how I got here!)

So, it looks like 'addRecords' means add or update.

FYI, Murray

1
votes

With ExtJS 4.1, here is an override :

In CoffeeScript :

# Adds "reload" to models
Ext.define "Ext.ux.data.Model",

    override: "Ext.data.Model",

    # callBack is called with success:boolean
    reload: (callBack) ->
        Ext.getClass(@).load @getId(),
            success : (r, o) =>
                for k, v of r.data
                    @data[k] = v
                @commit()
                callBack(true) if Ext.isFunction(callBack)

            failure: =>
                callBack(false) if Ext.isFunction(callBack)

In JS (did not test) :

Ext.define("Ext.ux.data.Model", {

    override: "Ext.data.Model",

    reload: function(callBack) {

        var me = this;
        return Ext.getClass(this).load(this.getId(), {
            success: function(r, o) {
                var k;
                for (k in r.data) {
                    me.data[k] = r.data[k];
                }
                me.commit();
                if (Ext.isFunction(callBack)) {
                    callBack(true);
                }
            },
            failure: function() {
                if (Ext.isFunction(callBack)) {
                    callBack(false);
                }
            }
        });
    }
});
0
votes

I created an override on the Ext.data.Model to add an additional method that can be used to update the data of an existing record (model instance).

Ext.define('Ext.overrides.data.Model', {
    override: 'Ext.data.Model',

    /**
     * Refresh the data of a record from the server
     */
    reloadData: function(cb) {
         var me = this;

         var id = me.getId();

         Ext.ModelManager.getModel(me.modelName).load(id, {
            callback: function(record, operation, success) {
                if (!success) {
                    Ext.Error.raise('Problem reloading data from server in record');
                }
                if (!record) {
                    Ext.Error.raise('No record from server to reload data from');
                }
                //change the data of the record without triggering anything
                Ext.apply(me.data, record.getData());

                //call a final callback if it was supplied
                if (cb) {
                    cb.apply(me, arguments);
                }
            }
        });

        return me;
     }
});

This is how you can use it. It's actually pretty simple:

myRecord.reloadData(function(record, operation, success) {
    //Done updating the data in myRecord
});

Internally it uses the load method on the associated model to create a new record. That new record is based on the same id as the original record that the reloadData method was called on. In the callback the data of the new record is applied to the data of the original record. No events triggered, which is probably hat you want.

This is Ext 4.2.1. There's probably dozens of scenario's that this solution breaks but we can always refine can't we.

Update: This solution basically implements the same as the one by @Drasill. Oh well... This one was tested though.