视图实体模型和数据绑定-View Models and Data Binding

数据绑定和 ViewModel 是 Ext JS 的强大功能。组合应用这两个技术,可以用声明的方式编写更少量的代码,而且更便于维护。

ViewModel 是管理数据对象的类。允许其他对象绑定到该数据,当数据发生变更时通知对象。与视图控制器一样,ViewModel 也属于它关联的视图。通过组件的层次结构也可以关联到上级组件的 ViewModel。这使得子视图可以继承父视图 ViewModel 的数据。

组件有个 bind 配置属性,可以将组件的许多配置属性绑定到 ViewModel 的数据。通过数据绑定,当数据发生变化时,可以确保调用组件配置属性的 setter 方法,不用编写自定义的事件处理。

组件绑定-Component Binding

理解数据绑定和 ViewModel 最好的方法是了解一下组件绑定的各种方式。组件是使用数据绑定的主要对象。要使用数据绑定,首先要有引用一个 VieModel。

绑定和配置-Binding and Configs

组件的数据绑定,实际上就是将 Ext.app.ViewModel 的数据对象链接到组件的配置属性(config properties)的处理。组件的所有配置属性都可以绑定,只要该属性有一个 setter 方法。例如:Ext.panel.Panel 有一个 setTitle() 方法,所以可以绑定 title 配置项。

Ext.create('Ext.panel.Panel', {
    title: 'Simple Form',

    viewModel: {
        type: 'test'  // we will define the "test" ViewModel soon
    },

    bind: {
        html: '<p>Hello {name}</p>',
        width: '{someWidth}'
    }
});

数据绑定的语法与 Ext.Template 的语法非常相似,将文本放在大括号内("braces")。也可以像 Ext.Template 那样使用格式化。

绑定布尔属性-Binding Boolean Configs

一些配置属性要求绑定布尔值,例如:visiblehiddendisabledcheckedpressed 等。 绑定模板支持以内联的方式( inline )求 。其他的数学运算可以使用公式,但是布尔求非运算可以用 ! 符号。例如:

Ext.create('Ext.panel.Panel', {
    title: 'Simple Form',

    viewModel: {
        type: 'test'
    },

    items: [{
        xtype: 'button',
        bind: {
            // negated
            hidden: '{!name}'
        }
    }]
});

绑定优先级-Binding and Priority

数据绑定的配置属性将总是覆盖直接设置的配置属性。换句话说,绑定的数据比静态配置优先级高,但是会存在一定的延迟(需要获取数据)。

Ext.create('Ext.panel.Panel', {
    title: 'Simple Form',

    viewModel: {
        type: 'test'
    },

    bind: {
        title: 'Hello {name}'
    }
});

当绑定的属性 name 有值时,原标题就会被替换。

绑定和子组件-Binding and Child Components

数据绑定非常有用的功能是,组件的所有子组件都可以访问组件的 ViewModel 的数据。例如:

Ext.create('Ext.panel.Panel', {
    title: 'Simple Form',

    viewModel: {
        type: 'test'
    },

    layout: 'form',
    defaultType: 'textfield',

    items: [{
        fieldLabel: 'First Name',
        // uses "test" ViewModel from parent
        bind: '{firstName}'
    },{
        fieldLabel: 'Last Name',
        bind: '{lastName}'
    }]
});

双向绑定-Two Way Binding

数据绑定允许使用双向绑定,在视图和实体模型之间同步数据。视图上发生变化的数据自动回写到模型中。这也将自动更新使用这些数据的其他组件。

备注:不是所有的配置属性在发生变更时都发布其变更值("publish")。

publishtwoWayBindable 数组中定义的配置属性才能自动回写到 ViewModel。也可以使用组件或应用的 publishState 方法发布变更值。完整的示例如下:

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

    // connects to viewModel/type below
    alias: 'viewmodel.test',

    data: {
        firstName: 'John',
        lastName: 'Doe'
    },

    formulas: {
        // We'll explain formulas in more detail soon.
        name: function (get) {
            var fn = get('firstName'), ln = get('lastName');
            return (fn && ln) ? (fn + ' ' + ln) : (fn || ln || '');
        }
    }
});

Ext.define('MyApp.view.TestView', {
    extend: 'Ext.panel.Panel',
    layout: 'form',

    // Always use this form when defining a view class. This
    // allows the creator of the component to pass data without
    // erasing the ViewModel type that we want.
    viewModel: {
        // references alias "viewmodel.test"
        type: 'test'
    },

    bind: {
        title: 'Hello {name}'
    },

    defaultType: 'textfield',
    items: [{
        fieldLabel: 'First Name',
        bind: '{firstName}'
    },{
        fieldLabel: 'Last Name',
        bind: '{lastName}'
    },{
        xtype: 'button',
        text: 'Submit',
        bind: {
            hidden: '{!name}'
        }
    }]
});

Ext.onReady(function () {
    Ext.create('MyApp.view.TestView', {
        renderTo: Ext.getBody(),
        width: 400
    });
});

绑定和组件状态-Binding and Component State

有时一些组件的状态,例如:复选框的 checked 状态或者 grid 选择的记录等,与其他组件相关。当组件使用 reference 配置标识时,组件将在 ViewModel 中发布一些关键的属性。这种方法非常适用于动态表单。例如:

Ext.create('Ext.panel.Panel', {
    title: 'Sign Up Form',

    viewModel: {
        type: 'test'
    },

    items: [{
        xtype: 'checkbox',
        boxLabel: 'Is Admin',
        reference: 'isAdmin'
    },{
        xtype: 'textfield',
        fieldLabel: 'Admin Key',
        bind: {
            disabled: '{!isAdmin.checked}'
        }
    }]
});

绑定描述符-Bind Descriptors

上述示例已经演示了三种绑定说明符:

  • {firstName} - 直接绑定到 ViewModel 的一些值。
  • Hello {name} - 绑定模板("bind template")。使用一些绑定表达式处理一些文本值,也可以使用格式化,例如:'Hello {name:capitalize}'
  • {!isAdmin.checked} - 布尔运算。

除了这些基本形式,还可以使用一些特殊的形式。

多重绑定-Multi-Bind

如果绑定描述符使用对象或数据,那么 ViewModel 将生成相同形式的对象或数组,用绑定的结果替换各个属性,例如:

Ext.create('Ext.Component', {
    bind: {
        data: {
            fname: '{firstName}',
            lname: '{lastName}'
        }
    }
});

记录绑定-Record Bind

当需要一个特殊记录时,绑定说明符可以是一个对象,并且设置 "reference" 属性。例如:

Ext.create('Ext.Component', {
    bind: {
        data: {
            reference: 'User',
            id: 42
        }
    }
});

上述示例中,组件的 tpl 接收 User 实体记录。这种方式需要使用 Ext.data.Session

关联绑定-Association Bind

与记录绑定相似,可以绑定关联的实体记录,例如:用户地址:

Ext.create('Ext.Component', {
    bind: {
        data: {
            reference: 'User',
            id: 42,
            association: 'address'
        }
    }
});

绑定选项-Bind Options

最后一种形式是绑定选项。下述示例演示了如何从一个绑定只接收一个值,然后自动断开连接:

Ext.create('Ext.Component', {
    bind: {
        data: {
            bindTo: '{name}',
            single: true
        }
    }
});

results matching ""

    No results matching ""