9

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.

MJC
  • 3,871
  • 4
  • 23
  • 34

4 Answers4

6

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

Murrah
  • 1,508
  • 1
  • 13
  • 26
  • 2
    Unfortunately, this reset the scrolling position and added the updated records always at the end of my grid. I used a modified version of a script found here instead: http://vadimpopa.com/reload-a-single-record-and-refresh-its-extjs-grid-row/ – RobDil Jun 23 '13 at 21:51
4

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.

Simon Elliston Ball
  • 4,375
  • 1
  • 21
  • 18
  • The load function (on the Model) builds another record (and that's why a posted this question :D ) when i dblclick the item i got the record already, and i only want to reload it, not build another, or if so, how to replace the old one cleanly. Thank you Simon. – MJC Jun 03 '11 at 14:47
  • If you are wanting to check the freshness against the server, then you will have to load a new version. If you want to stick solely to the grid's backing store, instead of using the standalone model, you will have to remove the record from the store, and then load({add: true}) on the grid store using a url that just grabs the relevant record. – Simon Elliston Ball Jun 03 '11 at 14:57
  • so, there's no way to reload it... ok, thank you, i'll accept your answer because it actually helped me on the "refresh grid" issue. i was afraid that it would flick or something when i deleted and then added (or vice-versa) the records in question. thank you. – MJC Jun 03 '11 at 15:40
  • 3
    This solution sucks, because you're creating another object in memory - and the item in the store will be out of sync if you update the newly loaded item. – Subimage Sep 09 '12 at 01:20
  • Hi Simon, in fact I am curious to see the link you provided above but it is not working. can you post new link please? – I3i0 Dec 03 '13 at 18:03
  • Hi, sorry about that, I've fixed the link now, should go to the latest docs. – Simon Elliston Ball Dec 03 '13 at 19:57
1

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);
                }
            }
        });
    }
});
Drasill
  • 3,917
  • 29
  • 30
0

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.

Christiaan Westerbeek
  • 10,619
  • 13
  • 64
  • 89