EXTJS 6.5 将 View 模型中的存储数据绑定(bind)到 View 中的字段

标签 extjs mvvm binding

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

应用程序.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'
                    }
                ]
            }
    ]
});

app/view/main/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);
    }

});

应用程序/ View /main/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 中的硬编码数据的绑定(bind)数据,但没有看到我希望从我的商店数据中看到的“12345678”

enter image description here

然后我在表单字段中输入一些值并单击更新,可以看到我在 Controller 的函数中并且数据已更新,这就是我希望在我的使用值 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;
        }
    },
    

    和我的表单字段绑定(bind)到
    {   xtype:'displayfield',
        label: 'Store Data Bound Field',
        bind: {
                value: '{getData.barcode}'
        }
    }
    

    现在,当我加载表单时,我看到了来自商店的绑定(bind)数据
    enter image description here

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

    enter image description here

    enter image description here

    最佳答案

    您需要更新您的自定义 property 值,就像您使用 getData 一样。您只是在更新 store 值,它不反射(reflect) getData 值。因此,您必须将 getData 更新为相同的值。

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

    代码片段

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

    关于EXTJS 6.5 将 View 模型中的存储数据绑定(bind)到 View 中的字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48666522/

    相关文章:

    javascript - 单击 ExtJS 中的标题对网格中的日期列进行排序

    Extjs 4 GridPanel : how can I get the row-index (position) of an element by id

    wpf - 使用相同ViewModel的MVVM New窗口

    wpf - 不会发生WPF MVVM TextBox更新

    asp.net-mvc-2 - ASP.NET MVC 默认 View 模型 cookie 到自定义对象的绑定(bind)

    javascript - Extjs树面板加载器ajax调用

    javascript - ie8 中此操作错误的源 HTML 无效

    c# - 在 MVVM 中实现 ICommand 时,我遗漏了一些东西

    wpf - 从代码隐藏绑定(bind)字符串格式?

    c# - 无法在将 DataView 实例作为项目源的 WPF 数据网格中显示数据