1. #31
    Sencha Premium Member
    Join Date
    Jul 2012
    Posts
    8
    Vote Rating
    1
    bldoron is on a distinguished road

      1  

    Default


    That won't do, as the nameProperty field will only except one level. So
    It will change {AutoUsers:} to: {Auto.users:} for example, but not to: {auto: {users:}}

  2. #32
    Sencha User
    Join Date
    Dec 2009
    Location
    Enschede, The Netherlands
    Posts
    327
    Vote Rating
    13
    Answers
    16
    flanders will become famous soon enough

      0  

    Default


    Sorry for necro-ing this thread, but I hope this might be handy for anyone trying to safe a hasMany relation. I have made some adjustments to the code of @olivierpons. His code didn't work for me and I do not want to check for modified records but want to send everything. Code below was tested against 4.1.1

    Code:
    var ExtDataWriterJsonOriginal_getRecordData = Ext.data.writer.Json.prototype.getRecordData;
    Ext.data.writer.Json.override({
        getRecordData: function(record) {
            var me = this, i, association, childStore, data = {};
            data = ExtDataWriterJsonOriginal_getRecordData(record);
    
    
            /* Iterate over all the hasMany associations */
            for (i = 0; i < record.associations.length; i++) {
                association = record.associations.get(i);
                if (association.type == 'hasMany')  {
                    data[association.name] = [];
                    childStore = eval('record.'+association.name+'()');
    
    
                    //Iterate over all the children in the current association
                    childStore.each(function(childRecord) {
    					data[association.name].push(childRecord.getData());
                    }, me);
                }
            }
            return data;
        }
    });

  3. #33
    Sencha User olivierpons's Avatar
    Join Date
    Dec 2009
    Location
    Aix en Provence,France
    Posts
    116
    Vote Rating
    1
    Answers
    6
    olivierpons is on a distinguished road

      0  

    Default


    Thank you very much for following this, I have small problems with grids, I suppose it has something to do with my code, so I'll try yours and if things come better I'll let you know

    Olivier Pons

  4. #34
    Sencha User
    Join Date
    Dec 2009
    Location
    Enschede, The Netherlands
    Posts
    327
    Vote Rating
    13
    Answers
    16
    flanders will become famous soon enough

      0  

    Default


    I have updated the code so that it overrides as encouraged by Sencha and so that it still sends all fields, even those unchanged, which the previous version didn't (for some reason)

    Code:
    Ext.override(Ext.data.writer.Json, {
        getRecordData: function(record) {
            var me = this, i, association, childStore,
                data = this.callParent(arguments);
    
    
            /* Iterate over all the hasMany associations */
            for (i = 0; i < record.associations.length; i++) {
                association = record.associations.get(i);
                if (association.type == 'hasMany')  {
                    data[association.name] = [];
                    childStore = eval('record.'+association.name+'()');
    
    
                    //Iterate over all the children in the current association
                    childStore.each(function(childRecord) {
                        data[association.name].push(childRecord.getData());
                    }, me);
                }
            }
    
    
            return data;
        }
    });

  5. #35
    Sencha User
    Join Date
    Jul 2012
    Posts
    15
    Vote Rating
    1
    stephenr85 is on a distinguished road

      0  

    Default Sencha Touch revision

    Sencha Touch revision


    I landed here because I had this problem in Sencha Touch. Here's the code ported over to Touch-friendliness (2.0.1.1), for anyone interested.

    Code:
    Ext.define('Ext.data.writer.override.Json', {    override: 'Ext.data.writer.Json',
        getRecordData: function(record) {
            var me = this, i, association, type, key, store, childData,
                data = this.callParent(arguments),
                associations = typeof record.getAssociations === 'function' ? record.getAssociations() : [];
            
            for (i = 0; i < associations.length; i++){
                association = associations.get(i);
                type = association.getType();
                key = association.getAssociationKey();
                    
                if (type.toLowerCase() == 'hasmany'){
                    store = record[association.getName()]();
                    
                    if(store && store.getCount() > 0){
                        //Nest all of the store items.
                        data[key] = [];                
                        store.each(function(childRecord) {
                            data[key].push(childRecord.getData());
                        }, me);
                        
                    }
                    //If the store is empty and the key already exists with items, make it an empty array.
                    else if(data[key] && data[key].length){
                        data[key] = [];
                    }
                }
            }
    
    
    
    
            return data;
        }
    });
    Last edited by stephenr85; 5 Oct 2012 at 11:21 AM. Reason: removed logging from code

  6. #36
    Sencha User
    Join Date
    Oct 2012
    Posts
    1
    Vote Rating
    0
    rmetrich is on a distinguished road

      0  

    Default Not working when only associated data is changed

    Not working when only associated data is changed


    This code gets not called when only the associated data has been updated for a given record since Ext.data.Store.sync() will not find anything to update.

  7. #37
    Sencha User
    Join Date
    Nov 2012
    Posts
    4
    Vote Rating
    0
    MikeMueller is on a distinguished road

      0  

    Default record not saved

    record not saved


    I used the code from flanders. It works only if the data of the main model is changed. If I only change the associated data, I need to call manually
    Code:
    record.dirt=true;
    store.sync();
    Has anyone a solution for that?

    Thx Mike

  8. #38
    Sencha User
    Join Date
    Dec 2009
    Location
    Enschede, The Netherlands
    Posts
    327
    Vote Rating
    13
    Answers
    16
    flanders will become famous soon enough

      0  

    Default


    Have you explored the source? If you step through the call through sync() you can most likely see how it is determined which records are dirty. If you can override this method with an extra hook to check for changed parts your done.

  9. #39
    Sencha User
    Join Date
    Nov 2012
    Posts
    4
    Vote Rating
    0
    MikeMueller is on a distinguished road

      0  

    Default


    Thx flanders.

    I write two functions for the store to check all associations too

    Code:
    Ext.override(Ext.data.Store, {
            filterNew:function(record) {
                var me = this, i, association, childStore, childRecordPhantom=false;
    
                if( record.phantom === false && record.associations.length )
                {
                    for (i = 0; i < record.associations.length; i++)
                    {
                        association = record.associations.get(i);
                        if (association.type == 'hasMany')
                        {
                            childStore = eval('record.'+association.name+'()');
                            childStore.each(function(childRecord) {
                                childRecordPhantom = childRecord.phantom === true && childRecord.isValid();
                                if( childRecordPhantom )
                                {
                                    return false;
                                }
                            }, me);
                            if( childRecordPhantom )
                            {
                                break;
                            }
                        }
                    }
                }
    
                return childRecordPhantom || record.phantom === true && record.isValid();
            },
            filterUpdated: function(record) {
                var me = this, i, association, childStore, childRecordDirty=false;
    
                if( record.dirty === false && record.phantom === false && record.associations.length )
                {
                    for (i = 0; i < record.associations.length; i++)
                    {
                        association = record.associations.get(i);
                        if (association.type == 'hasMany')
                        {
                            childStore = eval('record.'+association.name+'()');
                            childStore.each(function(childRecord) {
                                childRecordDirty = childRecord.dirty === true && childRecord.phantom !== true && childRecord.isValid();
                                if( childRecordDirty )
                                {
                                    return false;
                                }
                            }, me);
                            if( childRecordDirty )
                            {
                                break;
                            }
                        }
                    }
                }
    
                return childRecordDirty || record.dirty === true && record.phantom !== true && record.isValid();
            }
        });
    Now I just have to call
    Code:
    store.sync();
    But I cant find a way to use autostore on the master models store, so I only need to modfiy child model data. Have you another hint for me?
    I find a function "afterEdit" on the model which fires the "afterEdit" event on the associated store, but this needs to bubble up to the master model store. I dont know how this can be done.

    Thx Mike

  10. #40
    Sencha User
    Join Date
    Dec 2009
    Location
    Enschede, The Netherlands
    Posts
    327
    Vote Rating
    13
    Answers
    16
    flanders will become famous soon enough

      0  

    Default


    How about looking for the code that creates the childStore? At that point, you can add an afteredit listener to that store I think?