如何将ViewModel Store绑定到View?

7
我对Ext JS还比较新,正在尝试将MultiSelect嵌入到Panel中。

如您所见,ViewModel有一个stores属性:

Ext.define('TEST.view.controls.search.SearchFilterModel', {
    extend: 'Ext.app.ViewModel',
    alias: 'viewmodel.filter',
    data: {
        title: ''
    },
    stores: {
        test: {
            fields: ['id', 'name'],
            proxy: {
                type: 'ajax',
                url: 'api/test',
                reader: 'array'
            },
            autoLoad: true
        }
    }
});

我想在我的视图中绑定它,就像这样:<View>
viewModel: {
    type: 'filter'
},


layout: 'fit',
border: 1,
plain: true,
scrollable: 'y',
layout: 'fit',


bind: {
    title: '{title}',
},


items: {
    xtype: 'multiselect',
    scrollable: false,
    allowBlank: true,
    ddReorder: true,
    bind: {
        store: '{test}'
    },
    valueField: 'id',
    displayField: 'name'
}

在这种情况下,store最终变成了null,并且没有任何数据加载到小部件中。如果不绑定存储,而是在视图中直接硬编码,则可以解决问题。

有人看出问题所在了吗?


你为什么决定该存储为空?对我来说,提供的片段很好,应该可以工作。你应该提供视图的所有代码,最好提供jfiddle或sencha fiddle以演示问题。 - yorlin
@yorlin - 谢谢,我会尝试编写一个Sencha Fiddle。错误是Uncaught TypeError: Cannot read property 'autoCreated' of null - Dave L.
我有与您的视图完全相同的绑定结构,但对于组合框却不起作用。在设置“queryMode:local”进行组合时浪费了很多时间,现在它可以工作了。 :| - Mohammadreza
2个回答

6
您可以在绑定存储的同时传递一个空对象作为存储,这样initComponent将能够正常工作,例如:
{
    xtype: 'multiselect',
    fieldLabel: 'Multiselect',
    store: {},
    bind: {
        store: '{test}'
    },
    valueField: 'id',
    displayField: 'name'
}

工作示例:https://fiddle.sencha.com/#fiddle/ur8

(说明:此链接为一个it技术的工作演示示例)

你认为这是一个错误还是只是未记录的怪异现象?像这样需要两次传递“store”是很常见的吗? - Dave L.
1
实际上,当您绑定存储时,首先ExtJS创建一个空存储(不是null,而是一个临时存储),然后绑定一个普通存储。问题是绑定是异步的并且有延迟。问题是在您想要访问存储时。可能是,您试图访问存储时,即使是空存储,ExtJS也没有准备好。 - yorlin
@yorlin -- 这是有道理的,但我认为这是新的ExtJS开发人员不需要知道的实现细节。而且它需要与 store 相关的看起来冗余的语法。 - Dave L.
我曾经遇到过同样的问题,当我尝试添加:store: {},时,绑定延迟导致我的多选框没有下拉列表。我使用了这个:Custorm for work on Modern - Meas

1
这是一个常见的问题。只要您在商店中使用代理,就必须在视图呈现后加载商店。基本上,将这个代码添加到您的View中即可:
listeners: {
            afterrender: function(view) {
                this.getViewModel().getStore('{test}').load(); // this will provide proxy is being loaded
            }
           }

编辑:我没有注意到你已经添加了autoLoad: true。经过一些研究,多选组件在渲染期间必须获取“store对象”。这就是为什么会出现“autoCreated”错误的原因。我的意思是,在创建多选组件之前,必须先创建其存储。在您的情况下,您的多选组件首先被创建,然后将存储绑定到多选组件。要解决此问题,请检查此fiddle:https://fiddle.sencha.com/#fiddle/uqu

listeners: {
                afterrender: function(view) {
                    view.add({
                        xtype: 'multiselect',
                        scrollable: false,
                        allowBlank: true,
                        ddReorder: true,
                        fieldLabel: 'Multiselect',
                        store: view.getViewModel().getStore('test'), // comment to get autoCreated error
                        valueField: 'id',
                        displayField: 'name'
                    });
                }  
            },

+1,但我更喜欢另一个解决方案。虽然两个都不是很令人满意。对我来说似乎是个错误。 - Dave L.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接