Search code examples
javascriptextjsextjs4extjs5

extjs 5 store sync on binding to selection hasMany


How to get a store which is bound and filterd a viewModel.hasMany relationship synced?

I do have two grid panels in extjs5. say the first grid is groups and the second users. I bound the groups grid to viewModel stores.groups. This groups store is working and also syncing through the the models proxy (model is bound in the viewModel). The second grid is bound to the same viewModel through bind:{groupsReference.selection.users}. The binding works. On selection of a group the users are filtered. Changing some User data marks the user record as dirty.

The Problem: Dirty Users are not autoSynced any more, nor am I able to figure out how to sync it manually. How can I get autoSynced working here? How can I trigger a manual sync?

The models for groups for users are identical except the hasMany/belongsTo relationship:

Ext.define('MyApp.model.Groups', {
    extend: 'Ext.data.Model',

    fields: [
        { name: 'id', type: 'int' },
        { name: 'groupname', type: 'auto' }
    ],
    autoLoad: true,
    autoSync: true,
    proxy: {
        type: 'rest',
        url: '/api/groups',
        reader: {
            type: 'json',
            rootProperty: 'data',
            successProperty: 'success'
        },
        writer: {
            type: 'json'
        }
    },
    hasMany: {
        model: 'MyApp.model.Users',
        store:'MyApp.model.Users',
        name: 'users',
        foreignKey:'testId',
    }
});

And the view Model

Ext.define('MyApp.view.main.MainModel', {
    extend: 'Ext.app.ViewModel',
    requires: ['MyApp.model.Groups','MyApp.model.Users'],
    alias: 'viewmodel.main',
    stores: {
        groups: {
            model: 'mfct.model.Experiment',
            autoLoad:true,
            autoSync:true
        },
        users: {
            model: 'mfct.model.Variation',
            autoLoad:true,
            autoSync:true
        }
    }

});

Solution

  • This is my code, it might not be the best approach but at least it's working. Hope this could help you a bit.

    FabricOrder Model

    Ext.define('MyApp.model.FabricOrder', {
        extend: 'Ext.data.Model',
    
        requires: [
            'MyApp.model.SizeInfo'
        ],
    
        fields: [
            {name: '_id', type: 'string'},
            {name: 'styleno', type: 'string'},
            {name: 'modelname', type: 'string'},
            {name: 'colour', type: 'string'},
            {name: 'contractno', type: 'string'},
            {name: 'total', type: 'int'},
            {name: 'deliverydate', type: 'date', dateFormat: 'Y-m-d'},
            {name: 'comment', type: 'string'}
        ],
    
        hasMany: [{
            model: 'MyApp.model.SizeInfo',
            name: 'sizes'
            // This is not working in Extjs 5.0.0
            //storeConfig: {
            //   autoSync: true,
            //   proxy: {//etc.}
            //}
        }],
    
        idProperty: '_id'
    });
    

    SizeInfo Model

    Ext.define('MyApp.model.SizeInfo', {
        extend: 'Ext.data.Model',
    
        fields: [
            {name: 'size', type: 'string'},
            {name: 'amount', type: 'int'}
        ]
    });
    

    ViewModel

    Ext.define('MyApp.view.fabric.FabricModel', {
        extend: 'Ext.app.ViewModel',
    
        requires: [
            'MyApp.model.FabricOrder'
        ],
    
        alias: 'viewmodel.fabric',
    
        data: {
    
        },
    
        stores: {
            fabricOrders: {
                model: 'MyApp.model.FabricOrder',
                pageSize: 20,
                proxy: {
                    type: 'ajax',
                    actionMethods: {
                        create: 'POST',
                        read: 'POST',
                        update: 'POST',
                        destroy: 'POST'
                    },
                    api: {
                        create: '/createFabricOrder',
                        read: '/loadFabricOrder',
                        update: '/updateFabricOrder',
                        destroy: '/deleteFabricOrder'
                    },
                    reader: {
                        type: 'json',
                        rootProperty: 'fabricorders',
                        totalProperty: 'total'
                    }
                },
                autoSync: true,
                autoLoad: {start: 0, limit: 20},
    
                onCreateRecords: function(records, operation, success) {
                    console.log(records);
                },
    
                onUpdateRecords: function(records, operation, success) {
                    // If update failed, reject all changes
                    if(!success) {
                        // Call rejectChanges method of the store
                        this.rejectChanges();
    
                        Ext.Msg.show({
                            title: 'Update Failed',
                            message: 'The changes you have made are rejected.',
                            buttons: Ext.Msg.OK,
                            icon: Ext.Msg.ERROR
                        });
                    }
                },
    
                onDestroyRecords: function(records, operation, success) {
                    console.log(records);
                }
            },
    
            sizeInfos: {
                model: 'MyApp.model.SizeInfo',
                proxy: {
                    type: 'ajax',
                    actionMethods: {
                        create: 'POST',
                        read: 'POST',
                        update: 'POST',
                        destroy: 'POST'
                    },
                    api: {
                        create: '/createFabricOrder',
                        read: '/loadFabricOrder',
                        update: '/updateFabricOrder',
                        destroy: '/deleteFabricOrder'
                    },
                    reader: {
                        type: 'json',
                        rootProperty: 'fabricorders'
                    }
                },
    
                autoLoad: false,
                autoSync: false,
    
                onCreateRecords: function(records, operation, success) {
                    console.log(records);
                },
    
                onUpdateRecords: function(records, operation, success) {
                    // If update failed, reject all changes
                    if(!success) {
                        // Call rejectChanges method of the store
                        this.rejectChanges();
    
                        Ext.Msg.show({
                            title: 'Update Failed',
                            message: 'The changes you have made are rejected.',
                            buttons: Ext.Msg.OK,
                            icon: Ext.Msg.ERROR
                        });
                    }
                },
    
                onDestroyRecords: function(records, operation, success) {
                    console.log(records);
                }
            }
        }
    }); 
    

    View Controller

    Ext.define('MyApp.view.fabric.FabricController', {
        extend: 'Ext.app.ViewController',
    
        alias: 'controller.fabric',
    
        id: 'fabricController',
    
        init: function() {
             this.control({
                'grid[name=fabricgrid]': {
    
                },
                'grid[name=sizegrid]': {
                    reconfigure: 'onSizeGridReconfigure'
                }
             });
         },
    
        onSizeGridReconfigure: function(gird, store, columns, oldStore, oldColumns, eOpts) {
            if(store) {
                // Override the default association store settings
                store.autoSync = true;
                store.proxy = this.getViewModel().getStore('sizeInfos').getProxy();
                store.onCreateRecords = this.getViewModel().getStore('sizeInfos').onDestroyRecords
                store.onUpdateRecords = this.getViewModel().getStore('sizeInfos').onUpdateRecords;
                store.onDestroyRecords = this.getViewModel().getStore('sizeInfos').onDestroyRecords
            }
        }
    });