Search code examples
gridviewextjsdata-bindingdatastoreextjs6-modern

sencha, Grid not update automatically when a store is updated


Well consider the following test code, written in extjs 6.5 modern.

 Ext.define('myApp.store.Sections', {
     extend: 'Ext.data.Store',
     storeId: 'Sections',
     alias: 'store.sections',

     fields: ['name', 'event'],

     data: {
         items: [{
             name: 'blah',
             event: 'a'
         }, {
             name: 'hello',
             event: 'a'
         }, {
             name: 'world',
             event: 'a'
         }, {
             name: 'foo',
             event: 'b'
         }, {
             name: 'bar',
             event: 'b'
         }]
     },

     proxy: {
         type: 'memory',
         reader: {
             type: 'json',
             rootProperty: 'items'
         }
     }
 });
 Ext.create({
     xtype: 'container',
     title: 'Panel Title',
     iconCls: 'x-fa fa-html5',
     height: 400,
     width: 400,
     fullscreen: true,

     layout: {
         type: 'vbox',
         align: 'stretch'
     },
     items: [{
         xtype: 'grid',
         name: 'master',
         store: {
             type: 'sections',
         },
         layout: 'fit',
         flex: 1,
         plugins: {
             gridcellediting: {
                 selectOnEdit: true,
                 triggerEvent: 'tap',
             }
         },
         columns: [{
             text: 'name',
             dataIndex: 'name',
             flex: 1,
             editor: {
                 xtype: 'textfield',
             }
         }]
     }, {
         xtype: 'grid',
         name: 'firstslave',
         store: {
             type: 'sections',
         },
         layout: 'fit',
         flex: 1,
         columns: [{
             text: 'name',
             dataIndex: 'name',
             flex: 1
         }]
     }, {
         xtype: 'combobox',
         name: 'secondslave',
         displayField: 'name',
         valueField: 'name',
         store: {
             type: 'sections'
         }
     }]
 });

One can modify the store entries through the first grid. If the store is modified this way, the changes are visible inside the combobox (second slave).

However the second grid doesn't reflect those changes, there the items stay the same and thus the gridview is out of sync with the underlying data.

Why does this happen? Can this be prevented?

EDIT: I've noticed that if I reorder the grid (by means of the column menu) the items are updated.


Solution

  • As you are using store for you all component

    store: {
      type: 'sections'
    }
    

    So in that case every component have new instance of your sections store. That's why your changes is not reflecting.


    You can achieve your required result by using 2 way

    1. By using ViewModel and binding config

    2. You can directly assign the storeId to your component

      store:'sections' //In that case you store should be created
      

    In this FIDDLE, I have create demo using ViewModel and binding.

    Ext.application({
        name: 'Fiddle',
    
        launch: function () {
    
            Ext.define('myApp.store.Sections', {
                extend: 'Ext.data.Store',
                storeId: 'Sections',
                alias: 'store.sections',
    
                fields: ['name', 'event'],
    
                data: {
                    items: [{
                        name: 'blah',
                        event: 'a'
                    }, {
                        name: 'hello',
                        event: 'a'
                    }, {
                        name: 'world',
                        event: 'a'
                    }, {
                        name: 'foo',
                        event: 'b'
                    }, {
                        name: 'bar',
                        event: 'b'
                    }]
                },
    
                proxy: {
                    type: 'memory',
                    reader: {
                        type: 'json',
                        rootProperty: 'items'
                    }
                }
            });
    
            Ext.define('MainModel', {
                extend: 'Ext.app.ViewModel',
    
                alias: 'viewmodel.main',
    
                stores: {
                    myStore: {
                        type: 'sections'
                    }
                }
            });
    
            Ext.create({
                xtype: 'container',
                title: 'Panel Title',
                iconCls: 'x-fa fa-html5',
                //height: 400,
                fullscreen: true,
    
                viewModel: {
                    type: 'main'
                },
    
                layout: {
                    type: 'vbox',
                    align: 'stretch'
                },
                items: [{
                    xtype: 'grid',
                    title: 'Grid 1',
                    name: 'master',
                    bind: '{myStore}',
                    layout: 'fit',
                    flex: 1,
                    plugins: {
                        gridcellediting: {
                            selectOnEdit: true,
                            triggerEvent: 'tap'
                        }
                    },
                    columns: [{
                        text: 'name',
                        dataIndex: 'name',
                        flex: 1,
                        editor: {
                            xtype: 'textfield'
                        }
    
                    }]
                }, {
                    xtype: 'grid',
                    title: 'Grid 2',
                    name: 'firstslave',
                    bind: '{myStore}',
                    layout: 'fit',
                    flex: 1,
                    columns: [{
                        text: 'name',
                        dataIndex: 'name',
                        flex: 1
                    }]
                }, {
                    xtype: 'panel',
                    title: 'Combo panel',
                    items: [{
                        xtype: 'combobox',
                        name: 'secondslave',
                        displayField: 'name',
                        valueField: 'name',
                        bind: {
                            store: '{myStore}'
                        },
                        margin:'0 0 30 0'
                    }]
                }]
            });
        }
    });