1
votes

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
        }
    }

});
1
I have the same problem. Please let me know if you have solved it.. - Ian
I didn't really solve it yet. Added a save button to the grid and trigger the saving manually - Manuel
Thanks Manuel, I did some research yesterday and I found extjs will create an association store(which is a default store that will pick up the proxy defined in the model) and pass it to the grid if using the selection bind. I tried to pass the storeConfig when defining hasMany association, but it was not working. I ended up adding listener to the grid for the reconfigure event and set autoSync property to true there. - Ian
Sound interesting, could you share the code with me. How did you try to pass the storeConfig when defining hasMany association? Didn't knew that was possible? Is this a bug? Or a missing functionality? I'm pretty new to extjs, could you share the code? How do you bind to the reconfiguration event? - Manuel

1 Answers

0
votes

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
        }
    }
});