В соответствии с документацией
Когда выполняется прямая привязка, а свойство bound является объектом, по умолчанию обратный вызов привязки вызывается только при изменении этой ссылки. Это наиболее эффективный способ понять привязку этого типа, но иногда вам может потребоваться уведомление об изменении какого-либо свойства этого объекта.
Для этого мы создаем «глубокую привязку»:
Другими словами, если объект изменяет свои свойства, модель представления не будет уведомлять об этих изменениях (хотя их свойства изменены правильно).
Если вам необходимо прослушать эти изменения, вам нужно использовать глубокое связывание
Ext.application({
name : 'Fiddle',
launch : function() {
Ext.define('MyApp.view.TestViewModel', {
extend: 'Ext.app.ViewModel',
alias: 'viewmodel.userinfo',
data: {
persondetails: {
firstname: '',
lastname: ''
}
},
formulas: {
enableButton: {
bind: {
bindTo: '{persondetails}',
deep: true // listen to any change in personaldetails
},
get: function (data) {
return data.firstname && data.lastname
}
},
fullName: {
bind: {
bindTo: '{persondetails}',
deep: true // listen to any change in personaldetails
},
get: function (data) {
return data.firstname + ' ' + data.lastname
}
},
}
});
Ext.create('Ext.form.Panel', {
title: 'Contact Info',
width: 500,
bodyPadding: 10,
renderTo: Ext.getBody(),
viewModel:{
type:'userinfo'
},
items: [{
xtype: 'textfield',
name: 'firstname',
emptyText: 'Enter First Name',
bind: {
value: '{persondetails.firstname}'
},
}, {
xtype: 'textfield',
name: 'lastname',
emptyText: 'Enter Last Name',
bind: {
value: '{persondetails.lastname}'
},
}, {
xtype: 'button',
reference: 'clickme',
disabled: true,
bind: {
disabled: '{!enableButton}'
},
text: 'Click',
listeners: {
click: function(){
alert('{fullName}');
}
}
}, {
xtype: 'displayfield',
fieldLabel: 'Full Name',
bind: {
value: '{fullName}'
}
}]
});
}
});