Reputation: 4027
I created this fiddle where you can see what happens: https://fiddle.sencha.com/#view/editor&fiddle/3ndt
Ext.application({
name: 'Fiddle',
launch: function () {
Ext.define('MyViewModel', {
extend: 'Ext.app.ViewModel',
alias: 'viewmodel.myviewmodel',
data: {
items: ['Item 1', 'Item 2', 'Item 3']
},
stores: {
store: {
fields: ['item'],
data: []
}
},
formulas: {
itemCount: {
bind: {
bindTo: '{items}',
deep: true
},
get: function (data) {
//console.log(data);
return data.length;
}
},
}
});
Ext.create('Ext.panel.Panel', {
viewModel: {
type: 'myviewmodel'
},
items: [{
xtype: 'displayfield',
fieldLabel: 'Item Count',
bind: '{itemCount}'
//bind: '{store.count}'
}, {
xtype: 'button',
text: 'Add item',
style: 'margin-right: 10px;',
handler: function () {
//console.log('Button 1 clicked');
//debugger;
let vm = this.up('panel').getViewModel();
let stack = vm.get('items');
//debugger;
stack.push('Item 4');
console.log(stack);
let store = vm.getStore('store');
store.add({
item: 'Item'
});
console.log(store.data.items);
}
}],
renderTo: Ext.getBody()
});
}
});
The formula itemCount is deep bound to the array and it returns the number of items in the array. When I click on the Add Item button, I add an item in the array, however the itemCount formula is not re-evaluated.
Any idea why this limitation? I find it surprising.
As workaround, if I use a store and bind to the store.count property, then it works. Comment out bind: '{itemCount}'
and remove the comment from the line below, run the fiddle and click the Add Item button a few times.
Just a side note, I created this Vue playground and you can see that vue binds the array properly, i.e. if items are added to the array, then the length of the array is re-evaluated.
App.vue
<script setup>
import { ref } from 'vue'
const msg = ref('Hello World!')
const array = ref(['item 1', 'item 2', 'item 3'])
</script>
<template>
<h1>{{ msg }}</h1>
<input v-model="msg">
<br/>
<button @click="array.push('Item 4')">
Click me
</button>
<span> Array: {{array}}, length: {{array.length}}</span>
</template>
Upvotes: 0
Views: 266
Reputation: 9754
Try this code, just copy to your fiddle. It is not a perfect solution because it creates a new array each time.
Ext.application({
name: 'Fiddle',
launch: function () {
Ext.define('MyViewModel', {
extend: 'Ext.app.ViewModel',
alias: 'viewmodel.myviewmodel',
data: {
items: ['Item1', 'Item2', 'Item3']
},
formulas: {
itemCount: {
bind: '{items.length}',
get: function (data) {
console.log('Items length is now ' + data);
return data;
}
}
}
});
Ext.create('Ext.panel.Panel', {
viewModel: {
type: 'myviewmodel'
},
items: [{
xtype: 'displayfield',
fieldLabel: 'Item Count',
bind: '{itemCount}',
}, {
xtype: 'button',
text: 'Add item',
style: 'margin-right: 10px;',
handler: function () {
let vm = this.up('panel').getViewModel();
let stack = vm.get('items');
let newStack = Ext.Array.clone(stack);
newStack.push('Item ' + stack.length);
vm.set('items', newStack);
}
}],
renderTo: Ext.getBody()
});
}
});
Upvotes: 1