【问题标题】:EXTJS 6.5 Binding store data in viewmodel to field in viewEXTJS 6.5 将视图模型中的存储数据绑定到视图中的字段
【发布时间】:2018-02-07 14:42:01
【问题描述】:

不幸的是,我不知道如何使 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'
});

app/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']

});

app/model/Base.js

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

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

app/model/barcodeInfoModel.js

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

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

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

});

app/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 个显示字段,以及来自我在 viewModel 中的硬编码数据的绑定数据,但没有看到我希望从我的商店数据中看到的“12345678”

然后我在表单字段中输入一些值并单击更新,可以看到我在控制器的函数中并且数据已更新,这就是我希望看到我的“存储数据绑定字段”的地方" 在我的表单中更新为 55555555

虽然这只是一个简单的应用程序来演示我的问题,但最终我要做的是在条形码字段中接收条形码,通过 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}'
    }
}

现在,当我加载表单时,我会看到来自商店的绑定数据

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

【问题讨论】:

  • 您是否尝试指定该商店的记录:值:'{myStore.first().barcode}
  • 如果我将视图字段设置为bind: { value: '{myStore.first().barcode}' },我会收到“意外令牌”错误。
  • 如果我将 viewModel 的商店声明更改为 stores:{ myStore: { data: Ext.getStore('barcodeInfoStore').first() } },我会收到错误“无法读取未定义的属性 'first'”,这意味着它不知道我的商店,即使我可以去到浏览器的控制台并输入 Ext.getStore('barcodeInfoStore') 并获取对它的引用?

标签: extjs mvvm binding


【解决方案1】:

您需要更新您的自定义 property 值,就像您使用 getData 一样。您只是在更新 store 值,并没有反映 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'
});

【讨论】:

  • 谢谢 - 这是最接近我希望达到的目标的人。
猜你喜欢
  • 1970-01-01
  • 2013-09-25
  • 1970-01-01
  • 1970-01-01
  • 2017-10-25
  • 1970-01-01
  • 2011-04-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多