ExtJS 5.1: Binding record value to component prope

2019-01-29 13:26发布

问题:

Let's say I've got a ViewController, ViewModel, and my View. In the View, I've got a form panel that gets a loaded record. When this record loads into the form, I want to hide or show a button based on the record's status field, so I figured do something with binding. However, it looks like binding is limited to only inverting, not actually using an expression. To get a better understanding, take a look at this code:

Ext.application({
    name : 'Fiddle',

    launch : function() {
        Ext.define('User', {
           extend: 'Ext.data.Model',
           fields: ['name', 'status']    
        });

        Ext.define('UserListController', {
            extend : 'Ext.app.ViewController',
            alias: 'controller.userlist'
        });

        Ext.define('UserListViewModel', {
            extend: 'Ext.app.ViewModel',
            alias: 'viewmodel.userlist'
        });

        Ext.define('UserList', {
            extend: 'Ext.form.Panel',
            controller: 'userlist',
            viewModel: 'userlist',

            tbar: [{
                text: 'Add',
                reference: 'addButton',
                bind: {
                    //hidden: '{status == 2}'
                }
            }, {
                text: 'Delete',
                reference: 'deleteButton',
                bind: {
                    //hidden: '{status == 1}'
                }
            }],
            items: [{
                xtype: 'displayfield',
                name: 'name',
                fieldLabel: 'Name'
            }, {
                xtype: 'displayfield',
                name: 'status',
                fieldLabel: 'Status'
            }]
        });

        var myForm = Ext.create('UserList', {
            width: 400,
            height: 200,
            renderTo: Ext.getBody()
        });

        var record = Ext.create('User', {
            name: 'blah',
            status: 2
        });

        myForm.loadRecord(record);
        if (record.get('status') === 2) {
            myForm.lookupReference('addButton').hide();
        }
    }
});

As you can see, I'm currently just probing the values of the record to hide the addButton. Is there anyway I can accomplish this with binding or some other approach? It's good to note that I also looked at formulas, but from what I'm understanding, that's only for changing how data is rendered, so it didn't seem like the proper route.

回答1:

If your record is part of the view model data - use formulas, like:

formulas: {
    hideDeleteButton: function (getter) {
        return getter('record.status') === 2;
    },
    hideAddButton: function (getter) {
        return getter('record.status') === 1;
    }
}

And then in your view you can bind:

{
    text: 'Add',
    reference: 'addButton',
    bind: {
        hidden: '{hideAddButton}'
    }
}, {
    text: 'Delete',
    reference: 'deleteButton',
    bind: {
        hidden: '{hideDeleteButton}'
    }
}

A working example: https://fiddle.sencha.com/#fiddle/mcg