代码之家  ›  专栏  ›  技术社区  ›  Rytmis

Flex:是否存在无痛编程数据绑定?

  •  13
  • Rytmis  · 技术社区  · 16 年前

    ,如果我错了,请纠正我!)我收集到的信息表明,不能同时使用这两种方法——也就是说,在单独的ActionScript类文件中使用类功能,但在mxml中声明包含的元素。

    在生产率方面似乎没有太大差别,但以编程方式进行数据绑定似乎不那么简单。我了解了mxml编译器如何转换数据绑定表达式。结果是生成了大量回调,并且比mxml表示中的行多得多。所以问题是: 有没有一种方法可以以编程方式进行数据绑定,而不涉及大量的数据?

    4 回复  |  直到 16 年前
        1
  •  29
  •   Theo    16 年前

    不要害怕MXML。这是伟大的布局视图。如果你自己写 可重复使用的

    然而,纯ActionScript中的绑定不必那么痛苦。它永远不会像在MXML中那样简单,在MXML中为您做了很多事情,但它可以不费吹灰之力就完成。

    BindingUtils 这就是方法 bindSetter bindProperty . 我几乎总是使用前者,因为我通常想做一些工作或打电话 invalidateProperties 当值发生变化时,我几乎从不只想设置属性。

    您需要知道的是,这两个函数返回一个 ChangeWatcher ,如果出于某种原因要删除绑定,则必须保留此对象。这就是为什么ActionScript中的手动绑定比MXML中的手动绑定更不方便的原因。

    让我们从一个简单的例子开始:

    BindingUtils.bindSetter(nameChanged, selectedEmployee, "name");
    

    这将设置一个将调用该方法的绑定 nameChanged name 变量中对象上的属性 selectedEmployee 变化。这个 改名 方法将接收 名称 属性作为参数,因此它应该如下所示:

    private function nameChanged( newName : String ) : void 
    

    这个简单示例的问题是,一旦设置了此绑定,每次指定对象的属性更改时,它都会触发。变量的值 选定员工 可以更改,但仍然为变量之前指向的对象设置绑定。

    有两种方法可以解决这个问题:要么保持 变革观察者 BindingUtils.bindSetter 四处走动并打电话 unwatch 当您想要删除绑定(然后设置新绑定)或绑定到您自己时,请在上面单击。我将首先向您展示第一个选项,然后解释绑定到您自己是什么意思。

    这个 currentEmployee 可以制作成getter/setter对,并按如下方式实现(仅显示setter):

    public function set currentEmployee( employee : Employee ) : void {
        if ( _currentEmployee != employee ) {
            if ( _currentEmployee != null ) {
                currentEmployeeNameCW.unwatch();
            }
    
            _currentEmployee = employee;
    
            if ( _currentEmployee != null ) {
                currentEmployeeNameCW = BindingUtils.bindSetter(currentEmployeeNameChanged, _currentEmployee, "name");
            }
        }
    }
    

    现任雇员 属性时,它将查看是否存在以前的值,如果存在,则删除该对象的绑定( currentEmployeeNameCW.unwatch() ),然后设置私有变量,除非新值 null 为服务器设置新绑定 名称 变革观察者 由绑定调用返回。

    这是一个基本的绑定模式,我认为它工作得很好。然而,有一个技巧可以让它变得简单一点。你可以约束自己。而不是每次 现任雇员 属性更改您可以让绑定系统为您进行更改。在你的 creationComplete

    BindingUtils.bindSetter(currentEmployeeNameChanged, this, ["currentEmployee", "name"]);
    

    这种绑定不仅设置了 现任雇员 财产 this ,也是为了 名称 currentEmployeeNameChanged 将被调用。没有必要拯救这个世界 变革观察者 因为绑定永远不需要被移除。

    必须是事件调度器,并且 必须是可绑定的才能工作)。

        2
  •  8
  •   qualidafial    14 年前

    它从今天起就存在了。:)

    我刚刚发布了ActionScript数据绑定项目作为开源: http://code.google.com/p/bindage-tools

    BindageTools是BindingUtils的替代品(请参见此处的文字播放?),它使用流畅的API,您可以在其中以管道样式声明数据绑定:

    Bind.fromProperty(person, "firstName")
        .toProperty(firstNameInput, "text");
    

    Bind.twoWay(
        Bind.fromProperty(person, "firstName"),
        Bind.fromProperty(firstNameInput, "text"));
    

    Bind.twoWay(
        Bind.fromProperty(person, "age")
            .convert(valueToString()),
        Bind.fromProperty(ageInput, "text")
            .validate(isNumeric()) // (Hamcrest-as3 matcher)
            .convert(toNumber()));
    

    网站上还有更多的例子。还有很多其他的功能,来看看吧--马修

    编辑:更新的API

        3
  •  2
  •   Nick Higgs    16 年前

    package CustomComponents
    {
        import mx.containers.*;
        import mx.controls.*;
        import flash.events.Event;
    
        public class MyCanvasCode extends Canvas
        {
            public var myLabel : Label;
    
            protected function onInitialize(event : Event):void
            {
                MyLabel.text = "Lorem ipsum dolor sit amet, consectetuer adipiscing elit.";
            }
        }
    }
    

    …以及这样的标记:

    <?xml version="1.0" encoding="utf-8"?>
    <MyCanvasCode xmlns="CustomComponents.*" 
        xmlns:mx="http://www.adobe.com/2006/mxml"
        initialize="onInitialize(event)">
        <mx:Label id="myLabel"/>    
    </MyCanvasCode>
    

    从这个例子中可以看出,这种方法的一个缺点是必须声明如下控件 迈拉贝尔 在这两个文件中。

        4
  •  0
  •   Ruth Ruth    16 年前

    当做