1. #1
    Sencha User murrah's Avatar
    Join Date
    Oct 2007
    Location
    Katoomba, Blue Mountains, west of Sydney, Australia
    Posts
    387
    Vote Rating
    11
    murrah will become famous soon enough

      1  

    Default Solved: Ext.data.Model - persisting data via proxy and without a store

    Solved: Ext.data.Model - persisting data via proxy and without a store


    Hi.

    One use-case is as follows. A large database table with lots of columns that the user is allowed to edit. I am using a grid to list just the name column. The store model contains just the id and name to minimise the amount of data loaded. When I need to edit a selected record, I need to load all the data from the server for that record in order to populate the model on the form.

    One solution is to have a separate store whose model gets loaded to the form. But there will only ever be one record in the store, so really I need just the model with it's attached proxy to be able to load and save to the server.

    This is possible via the Model.load() and Model.save() methods, but the load() method in Ext4.2 wont work unless the id property is 'id'.

    A comment in the Ext.data.Model.load() docs by pschyska gave a heads up, but his override didnt work with ExtJS 4.2. I took the current load() method and reapplied his changes and this works. See override below.

    The other part to doing this is not necessarily clear - that is, the load() method is a static method and as such you call it as in the following example:

    Model:
    PHP Code:
    Ext.define('App.model.mTest', {
        
    extend'Ext.bux.data.Model',
        
    idProperty:'personid',

        
    fields: [
            
    'personid',
            
    'name'
        
    ]

        ,
    proxy: {
            
    type'rest',
            
    url'mypathtoserver' '/test',
            
    reader: {
                
    type'json',
                
    root'test',
                
    successProperty'success',
                
    totalProperty 'totalcount'
            
    }
        }
    }); 
    Use:
    PHP Code:
    App.model.mTest.load(1,{
        
    scopethis,
        
    failure: function(recordoperation) {
            
    mydebug.log('failure')
        },
        
    success: function(recordoperation) {
            
    mydebug.log('success')
             
    // Note that the record passed in is an instantiated App.model.mTest
             // containing the required data.
             // So, you could now load the reord to the form, for example:
             
             
    form.loadRecord(record);

        },
        
    callback: function(recordoperationsuccess) {
             
    mydebug.log('callback')
            
    //do something whether the load succeeded or failed
            //if operation is unsuccessful, record is null
        
    }            
    }); 
    To get the amended data from the form and save record data back to the server, you can do eg:
    PHP Code:
    var form    button.up('form'),
        
    record form.getRecord(),
        
    values form.getValues();

    record.set(values)
    record.save(); // This triggers the proxy to do it's thing 
    Finally, the edited record in the grid might need updating because the user might have changed the record's name. We have persisted the record to the server but the grid store is not refreshed. Rather than refresh from the server, just update the grid store model:
    PHP Code:
    // eg Get the first selected row
    var rec grid.getSelectionModel().getSelection().selection[0];
    // Dont tell the server (in case autoSync is on)
    grid.store.suspendAutoSync(); 
    // Update the name
    rec.set({ name values.name });
    // Clears the red dirty flag 
    rec.commit(); 
    // Resume sync
    rec.store.resumeAutoSync(); 
    The model override:
    PHP Code:
    /**
     * Override of Ext.data.Model ExtJS4.2
     * Override the load() static method so that it takes notice of any idProperty
     * that you have set. 
     * Credit to member pschyska
     * See http://docs.sencha.com/extjs/4.2.2/#!/api/Ext.data.Model-static-method-load
     * The Sencha Touch version of load() is slightly different but it looks like it 
     * handles the idProperty properly already. I havent tested it.
     */
    Ext.define('Ext.bux.data.Model', {
        
    extend'Ext.data.Model',
        
    statics: {

            
    load: function(idconfig) {
                
    //console.log('in bux.model load')

                
    config Ext.apply({}, config);

                    
    // Added this
                
    var params={};
                
    params[this.prototype.idProperty] = id;

                
    config Ext.applyIf(config, {
                  
    action'read',
                  
    paramsparams
                
    });
                    
    // end Added
                  
                  /* Removed this            
                  config = Ext.applyIf(config, {
                    action: 'read',
                    id    : id
                });*/

                
    var operation  = new Ext.data.Operation(config),
                    
    scope      config.scope || this,
                    
    callback;

                
    callback = function(operation) {
                    var 
    record null,
                        
    success operation.wasSuccessful();
                    
                    if (
    success) {
                        
    record operation.getRecords()[0];
                        
    // If the server didn't set the id, do it here
                        
    if (!record.hasId()) {
                            
    record.setId(id);
                        }
                        
    Ext.callback(config.successscope, [recordoperation]);
                    } else {
                        
    Ext.callback(config.failurescope, [recordoperation]);
                    }
                    
    Ext.callback(config.callbackscope, [recordoperationsuccess]);
                };

                
    this.getProxy().read(operationcallbackthis);
            }        
        }

        
    /**
         * Convenience method to set values to the model instance and save them via the proxy
         * 
         * @param  {Object} values  An object of the properties to set. Same as for Model.set()
         * @param  {Object} options The same options you can pass to Model.save() 
         * @return {Ext.bux.data.Model} The model instance
         */
        
    ,saveValuesViaProxy : function(values,options){
                                
    // The save() triggers the PUT, no autoSync available on the model it appears
                                // See http://edspencer.net/2011/02/02/proxies-extjs-4/
                                // options passed in can include a callback. Is Ext.data.Operation config
                                // see http://docs.sencha.com/extjs/4.2.2/#!/api/Ext.data.Model-method-save
            
    this.set(values);
            return 
    this.save(options);        
        }
    }); 
    I hope that all helps someone.
    Cheers,
    Murray

  2. #2
    Sencha - Support Team
    Join Date
    Feb 2013
    Location
    California
    Posts
    3,835
    Vote Rating
    72
    Gary Schlosberg is a jewel in the rough Gary Schlosberg is a jewel in the rough Gary Schlosberg is a jewel in the rough Gary Schlosberg is a jewel in the rough

      0  

    Default


    Thanks for sharing the fruits of your labor with the community.
    Get on the Fast Track with Sencha Training http://sencha.com/training

  3. #3
    Sencha User murrah's Avatar
    Join Date
    Oct 2007
    Location
    Katoomba, Blue Mountains, west of Sydney, Australia
    Posts
    387
    Vote Rating
    11
    murrah will become famous soon enough

      1  

    Default


    Quote Originally Posted by Gary Schlosberg View Post
    Thanks for sharing the fruits of your labor with the community.
    No worries. Just responding to the massive "pay forward" that is Ext/Sencha.

Thread Participants: 1

Tags for this Thread