Search code examples
extjsviewmodel

Not able to access object from data in ViewModel


Am trying to fetch the persondetails details into enableButton method. Am aware that we can achieve this by simply adding key and value to data object. But my question here is, is there any way to store data into persondetails and fetch it?

If I specify as below and bind accordingly, then its wok fine.

data: {
 firstname: '',
 lastname: ''
}

bind: {
  value: '{lastname}'
 },

Here is the code:

Ext.application({
    name : 'Fiddle',

    launch : function() {
        Ext.define('MyApp.view.TestViewModel', {
            extend: 'Ext.app.ViewModel',

            alias: 'viewmodel.userinfo',

            data: {
                persondetails:{
                    firstname: '',
                    lastname: ''
                }
            },
            formulas: {
                enableButton: function(get){
                    debugger;
                    if(get('firstname')!=='' && get('lastname')!=='' ){
                        return true;
                    }else{
                        return false;
                    }
                },
                fullName: function(get){
                    if(get('firstname')!=='' && get('lastname')!=='' ){
                        return get('firstname') + ' ' + get('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}'
                }
            }]
        });
    }
});

I have created a fiddle Example


Solution

  • According to documentation

    When a direct bind is made and the bound property is an object, by default the binding callback is only called when that reference changes. This is the most efficient way to understand a bind of this type, but sometimes you may need to be notified if any of the properties of that object change.

    To do this, we create a "deep bind":

    In other words, if a object changes its properties, the viewmodel will not notify these changes (although their properties are changed correctly).

    If you need to listen this changes, you need to use deep binding

    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}'
                    }
                }]
            });
        }
    });