I'm pretty new Ext JS and trying to embed a MultiSelect inside a Panel.
The
ViewModel
has astores
property as you can see here:
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
}
}
});
I would like to bind that in my
View
like this:
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'
}
In this case, the store
ends up as null
though and no data is loaded into the widget. Instead of binding the store though, if I just hardcode it in the View, then it works.
Anyone see what the issue is?
Binding using ViewModel First Approach There are two ways by which we can bind the View and View model in View First approach. The First is using the Code Behind. Suppose I have a ViewModel which is getting all the process of the system, as shown in the below code.
To set the datacontext in this way the ViewModel class need to have a default constructor. This is the preferable way of we not expecting any parameters for the constructor of View Model. The next approach is to use initialize the view model first. First lets check the MainWindow.xaml code
Now to bind the ViewModel (TaskViewModel in our case) and View (MainWindow.xaml) we have to write the below code. This is the code present in the MainWindow () constructor.The above code is setting the DataContext of the MainWindow as instance of the TaskViewModel. The ListBox is bound to the AllProcess property.
It has a property of type CustomerListViewModel named CurrentViewModel. This is the only code for View Model First Approach. And it is quite self explanatory. I have created a ContentControl in the MainWindow.xaml. The property to which it is bound is CurrentViewModel which is of type CustomerListViewModel in MainWindowViewModel.
You can pass an empty object as a store additionally to binding the store, that way the initComponent
will work, for example:
{
xtype: 'multiselect',
fieldLabel: 'Multiselect',
store: {},
bind: {
store: '{test}'
},
valueField: 'id',
displayField: 'name'
}
Working example: https://fiddle.sencha.com/#fiddle/ur8
It's common issue. As long as you use proxy in store, you have to load store after viewrendered. Basically, add this to your View
:
listeners: {
afterrender: function(view) {
this.getViewModel().getStore('{test}').load(); // this will provide proxy is being loaded
}
}
Edit: I didn't notice you already put the autoLoad: true
. After some research, multiselect component has to get "store object" during render. That's why you get the 'autoCreated' error. I mean, before multiselect is created, its store has to be created. In your case, your multiselect component is created first, then store is binded to multiselect. To fix this issue please check this 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'
});
}
},
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With