【问题标题】:Simplify AS3 binding/event-dispatching code简化 AS3 绑定/事件调度代码
【发布时间】:2009-12-08 11:42:25
【问题描述】:

有 3 个属性(示例 1):

[Bindable] public var name:String;
[Bindable] public var email:Number;
[Bindable] public var address:Boolean;

我需要有 3 个可以绑定的辅助方法(示例 2):

[Bindable] public var name:String;
[Bindable] public var email:Number;
[Bindable] public var address:Boolean;

public function get nameIsOk():Boolean     { return !Strings.isEmpty(name) }
public function get emailIsOk():Boolean    { return email == 3 }
public function get addressIsOk():Boolean  { return address }

当然,上面的代码不起作用。我通过这样做使其工作(示例 3):

private var _name:String
[Bindable("nameChanged")]
public function get name():String       { return _name }
public function set name(v:String):void { _name = v; dispatchEvent(new Event("nameChanged")) }
[Bindable("nameChanged")]
public function get nameIsOk():Boolean  { return !Strings.isEmpty(name) }

private var _email:Number
[Bindable("emailChanged")]
public function get email():Number       { return _email }
public function set email(v:Number):void { _email = v; dispatchEvent(new Event("emailChanged")) }
[Bindable("emailChanged")]
public function get emailIsOk():Boolean  { return email == 3 }

private var _address:Boolean
[Bindable("addressChanged")]
public function get address():Boolean       { return _address }
public function set address(v:Boolean):void { _address = v; dispatchEvent(new Event("addressChanged")) }
[Bindable("addressChanged")]
public function get addressIsOk():Boolean  { return address }

它确实有效,但现在它变得臃肿。

有没有办法将此代码(示例 3)缩减为更小的代码(如示例 2)?

更新: 感谢 just_a_dude 的好回答。这是最终版本:

[Bindable] public var name:String;
[Bindable] public var email:Number;
[Bindable] public var address:Boolean;

public function Remixer() {
    for each (var f:String in Strings.split("name email address")) {
        ChangeWatcher.watch(this, f, onChange)
    }
}

private function onChange(e:PropertyChangeEvent):void {
    dispatchEvent(new Event(e.property + "Changed"))
}

[Bindable("nameChanged")]
public function get nameIsOk():Boolean  { return !Strings.isEmpty(name) }

[Bindable("emailChanged")]
public function get emailIsOk():Boolean  { return email == 3 }

[Bindable("addressChanged")]
public function get addressIsOk():Boolean  { return address }

【问题讨论】:

    标签: apache-flex actionscript-3 binding event-handling


    【解决方案1】:

    不确定这是否是您要查找的内容,但您可以使用 mx.binding.utils.ChangeWatcher 来“监视”属性更改

    <?xml version="1.0" encoding="utf-8"?>
    

    <mx:Script>
        <![CDATA[
            import mx.events.PropertyChangeEvent;
            import mx.binding.utils.ChangeWatcher;
    
    
            [Bindable] public var firstName:String;
            [Bindable] public var email:Number;
            [Bindable] public var address:Boolean;
    
            private var _watcher:ChangeWatcher;
    
            private function init():void {
                ChangeWatcher.watch(this, "firstName", propertyChangeHandler);
                ChangeWatcher.watch(this, "email", propertyChangeHandler);
                ChangeWatcher.watch(this, "address", propertyChangeHandler);
    
                firstName = "foo";
                email = 0;
                address = true;
    
                firstName = "bar";
                email = 1;
                address = false;
            }
    
            protected function propertyChangeHandler(event:PropertyChangeEvent):void {
    
                var prop:Object = event.property;
                var name:String = prop.toString() + "Changed";
    
                // trace(name); // displays firstNameChanged or emailChanged or addressChanged
    
                dispatchEvent(new Event(name));
            }
    
    
        ]]>
    </mx:Script>
    

    如果这有帮助,请告诉我

    干杯

    【讨论】:

    • 这正是我想要的。谢谢!
    • 太棒了 :) 我总是很高兴能够提供帮助
    【解决方案2】:

    我不确定你是否需要 getter,但如果不需要,一个很好的方法是只使用一个函数,并将可绑定的字符串作为参数。

    如果你把它放在你的对象中:

    public function isOk(s:String):Boolean
    {
        return !Strings.isEmpty(s)
    }
    

    你会这样使用它:

    <mx:CheckBox selected="{yourObject.isOk(yourObject.name)}" />
    

    一般来说,如果你把一个函数放在“{}”里面,并且参数是可绑定的,那么每次参数改变时都会调用它。

    【讨论】:

    • 这可以简化为 -- 重要的是 isSomethingOk():Boolean 封装了一些隐藏的逻辑(不仅仅是字符串/空检查)并且不接受任何参数。将参数传递给 isOk(s:String):Boolean 会破坏封装并需要更多注意(您应该知道字段名称),这很容易出错。
    • 您更改代码的问题在于您不想要简单的功能。你真正想要的是一个完整的验证器,正如 Joa Ebert 所说,它应该是一个类。有几点可能会有所帮助: - 在当前版本中,您要发送许多消息;当电子邮件更改时,所有代码都被告知 isEmailOk 也发生了更改,而在大多数情况下不会发生这种情况。 - 验证代码可能会变得非常复杂并且其中包含多个变量,因此验证应该由任何变量的更改触发。
    【解决方案3】:

    我会将您的功能封装在一个类中。不要重复自己:)

    【讨论】:

      猜你喜欢
      • 2011-03-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多