EXTJS 6.5将viewmodel中的商店数据绑定到视图

时间:2018-02-07 14:42:01

标签: extjs mvvm binding

不幸的是我不知道如何让一个MVVM Modern应用程序在Fiddle工作,所以我必须在这里发布我的代码,但这里有一个简单的应用程序来演示我遇到的问题。

App.js

Ext.application({
    extend: 'simple.Application',

    name: 'simple',

    requires: [
        // This will automatically load all classes in the simple namespace
        // so that application classes do not need to require each other.
        'simple.*'
    ],

    // The name of the initial view to create.
    mainView: 'simple.view.main.Main'
});

应用程序/ application.js中

Ext.define('simple.Application', {
    extend: 'Ext.app.Application',

    name: 'simple',

    //my understanding is that I need to load my stores here in Application.js
    //as opposed to in the controller?
    requires: ['simple.store.barcodeInfoStore'],

    stores: ['barcodeInfoStore']

});

应用程序/模型/ Base.js

Ext.define('simple.model.Base', {
    extend: 'Ext.data.Model',

    schema: {
        namespace: 'simple.model'
    }
});

应用程序/模型/ barcodeInfoModel.js

Ext.define('simple.model.barcodeInfoModel', {
    extend: 'simple.model.Base',

    fields: [
        {name: 'barcode', type: 'string'},
        {name: 'status', type: 'string'}
    ]
});

应用程序/商店/ barcodeInfoStore.js

Ext.define('simple.store.barcodeInfoStore', {
    extend: 'Ext.data.Store',

    alias: 'store.barcodeInfoStore',

    model: 'simple.model.barcodeInfoModel',

    data: {
        items: [//here I'm just loading some dummy data to start
                {barcode:'12345678',status:'GOOD'}
            ]
    },

    proxy: {
        type: 'memory',
        reader: {
            type: 'json',
            rootProperty: 'items'
        }
    }
});

/app/view/main/Main.js

Ext.define('simple.view.main.Main', {
    extend: 'Ext.form.Panel',
    xtype: 'app-main',

    controller: 'main',
    viewModel: {
        type: 'main'
    },

    items: [{   xtype: 'formpanel',
                reference: 'form',
                items: [
                    {   xtype:'textfield',
                        label: 'Barcode',
                        placeholder: 'Barcode',
                        name: 'barcodeField',
                        reference: 'barcodeField',
                        allowBlank: false,
                        autoComplete: false
                    },
                    {   xtype:'textfield',
                        label: 'Status',
                        placeholder: 'Status',
                        name: 'statusField',
                        reference: 'statusField',
                        allowBlank: false,
                        autoComplete: false
                    },
                    {   xtype:'displayfield',
                        label: 'Fixed Data Bound Field',
                        bind: {
                            //test display field bound to some hard coded data
                            //in my viewModel just to verify that that works
                            //(it does)
                            value: '{fixedDataBarcode}'
                        }
                    },
                    {   xtype:'displayfield',
                        label: 'Store Data Bound Field',
                        bind: {
                            //test display field that I want to bind to store data
                            //(this DOES NOT work)
                            value: '{myStore.barcode}'
                        }
                    },
                    {
                        xtype:'button',
                        text:'Update',
                        handler:'onUpdateClicked'
                    }
                ]
            }
    ]
});

应用程序/视图/主/ MainController.js

Ext.define('simple.view.main.MainController', {
    extend: 'Ext.app.ViewController',

    alias: 'controller.main',

    //get a reference to my store and update the values in it
    //with the values from the form
    onUpdateClicked: function() {
        console.log('onUpdateClicked');
        var form = this.lookupReference('form');
        var formValues = form.getValues();

        var store = Ext.getStore('barcodeInfoStore');
        var data = store.getAt(0).data;

        data.barcode = formValues.barcodeField;
        data.status = formValues.statusField;

        console.log('Store Data Is Now ' + data.barcode + ', ' + data.status);
    }

});

应用程序/视图/主/ MainModel.js

Ext.define('simple.view.main.MainModel', {
    extend: 'Ext.app.ViewModel',

    alias: 'viewmodel.main',

    //this is where I'm trying to get a reference to my store
    //so I can bind data to it's values, but am not sure of the correct way
    //to do this?
    stores:{
        myStore: {
            data: Ext.getStore('barcodeInfoStore')
        }
    },

    //this is just some hard coded data to verify that I can bind to
    //data in my viewModel
    data: {
        name: 'simple',
        fixedDataBarcode: '11111111'
    }
});

当我加载我的应用程序时,我看到了界面,可以看到我的2个displayFields,并从viewModel中的硬编码数据中绑定数据,但没有看到我希望从我的商店数据中看到的“12345678”

enter image description here

然后我在表单字段中输入一些值,然后单击UPDATE,可以看到我在我的控制器的功能中,并且数据已经更新,这是我期望看到我的“存储数据绑定字段”的地方“在我的表格中更新了值55555555

enter image description here

虽然这只是一个简单的应用程序来演示我的问题,但最终我要做的是在条形码字段中接收条形码,通过Ajax查询数据库以获取数据,使用该数据更新商店并显示/使用该数据进行进一步处理。

所以我想我的问题是

  • 为什么这不能正常工作 - 如果你能帮助我纠正它,我确定我有什么问题?
  • 这种方法是接近我想要实现的目标的最佳方式还是有更好的方法?

更新: 我取得了一些进展。我将viewModel存储定义更改为

stores:{
        myStore: {
            //data: Ext.getStore('barcodeInfoStore')
            type: 'barcodeInfoStore'
    }
},

并添加了一个公式

formulas:{
    getData: function(get){
        console.log('in getData');
        return Ext.getStore('barcodeInfoStore').first().data;
    }
},

和我的表单字段绑定到

{   xtype:'displayfield',
    label: 'Store Data Bound Field',
    bind: {
            value: '{getData.barcode}'
    }
}

现在当我加载表单时,我会看到商店中的绑定数据 enter image description here

现在唯一的问题是,当我在表单中输入条形码/状态并单击更新商店中的数据的UPDATE时,绑定字段中的数据不会更新为新数据

enter image description here

enter image description here

1 个答案:

答案 0 :(得分:2)

您需要更新自定义property值,就像您采用getData一样。您只更新了store个值,但未反映getData个值。因此,您必须将getData更新为相同的值。

FIDDLE 中,我使用您的代码创建了一个演示并进行了一些修改。我希望这能帮助您/指导您解决您的问题/要求。

CODE SNIPPET

Ext.define('simple.model.Base', {
    extend: 'Ext.data.Model',

    schema: {
        namespace: 'simple.model'
    }
});

Ext.define('simple.model.barcodeInfoModel', {
    extend: 'simple.model.Base',

    fields: [{
        name: 'barcode',
        type: 'string'
    }, {
        name: 'status',
        type: 'string'
    }]
});

Ext.define('simple.store.barcodeInfoStore', {
    extend: 'Ext.data.Store',

    alias: 'store.barcodeInfoStore',

    model: 'simple.model.barcodeInfoModel',

    data: {
        items: [ //here I'm just loading some dummy data to start
            {
                barcode: '12345678',
                status: 'GOOD'
            }
        ]
    },

    proxy: {
        type: 'memory',
        reader: {
            type: 'json',
            rootProperty: 'items'
        }
    }
});

Ext.define('simple.view.main.MainModel', {
    extend: 'Ext.app.ViewModel',

    alias: 'viewmodel.main',

    stores: {
        myStore: {
            type: 'barcodeInfoStore'
        }
    },

    data: {
        formData: null
    },

    formulas: {
        setFormData: function (obj) {
            //Set formData value from myStore
            this.set('formData', this.get('myStore').first().data)
        }
    }

});

Ext.define('simple.view.main.Main', {
    extend: 'Ext.form.Panel',

    xtype: 'app-main',

    controller: 'main',

    viewModel: {
        type: 'main'
    },

    title: 'View Model example',

    items: [{
        xtype: 'textfield',
        label: 'Barcode',
        placeholder: 'Barcode',
        name: 'barcode',
        reference: 'barcodeField',
        allowBlank: false,
        autoComplete: false
    }, {
        xtype: 'textfield',
        label: 'Status',
        placeholder: 'Status',
        name: 'status',
        reference: 'statusField',
        allowBlank: false,
        autoComplete: false
    }, {
        xtype: 'displayfield',
        label: 'Store Data Bound barCode Field',
        bind: {
            value: '{formData.barcode}'
        }
    }, {
        xtype: 'displayfield',
        label: 'Store Data Bound Status Field',
        bind: {
            value: '{formData.status}'
        }
    }, {
        xtype: 'button',
        text: 'Update',
        ui: 'action',
        width: '100%',
        handler: 'onUpdateClicked'
    }]

});

Ext.define('simple.view.main.MainController', {
    extend: 'Ext.app.ViewController',

    alias: 'controller.main',

    /*
     * this function will fire on update button click
     * @param {Ext.Button} button
     */
    onUpdateClicked: function (button) {
        var form = button.up('formpanel'),
            formValues = form.getValues(),
            viewModel = this.getViewModel();

        //You need to update viewmodel properties to check binding
        viewModel.set('formData', formValues);
        console.log(`formData Is Now \n ${Ext.encode(viewModel.get('formData'))}`);

        //If you need to update data inside store then you need to use below code
        viewModel.get('myStore').getAt(0).set(formValues);
        console.log(`Store Data Is Now \n ${Ext.encode(viewModel.get('myStore').getAt(0).data)}`)
    }
});

Ext.define('simple.Application', {
    extend: 'Ext.app.Application',

    name: 'simple',

    //my understanding is that I need to load my stores here in Application.js
    //as opposed to in the controller?
    requires: ['simple.store.barcodeInfoStore'],

    stores: ['barcodeInfoStore']
});

Ext.application({
    extend: 'simple.Application',

    name: 'simple',

    requires: [
        // This will automatically load all classes in the simple namespace
        // so that application classes do not need to require each other.
        'simple.*'
    ],

    // The name of the initial view to create.
    mainView: 'simple.view.main.Main'
});