【问题标题】:Flex: passing parameters to custom componentsFlex:将参数传递给自定义组件
【发布时间】:2009-10-02 14:06:11
【问题描述】:

我正在尝试创建一个可以从 mxml 代码接收附加值的组件:

public class Board extends Canvas
{
    public var boardSize:Number;
    private var cellWidth:Number;
    public function Board()
    {
        super();

    }
}

如何从 mxml 代码中传递 boardSize 值。 例如

<MyComp:Board x="22" y="25" width="600" height="600" boardSize="19">

但它不起作用。当我尝试调试代码时,我看到 boardSize 变量在类中是 NaN

【问题讨论】:

    标签: apache-flex actionscript-3


    【解决方案1】:

    你什么时候测试这个?如果通过在构造函数中放置断点来测试代码,boardSize 应该为空。就像您的代码一样,通过 MXML 实例化需要在设置任何成员变量之前调用构造函数。

    例如,使用 TestObject 类试试这个应用程序。当你在调试模式下运行它时,trace 会告诉你 n 和 s 没有设置,但是当你看到应用程序时,在 trace 发生后,这两个标签是明确绑定的。

    <?xml version="1.0" encoding="utf-8"?>
    <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical" xmlns:local="*">
        <mx:TraceTarget />
        <local:TestObject id="o" n="19" s="19" />
        <mx:Label text="Number Field: {o.n}" />
        <mx:Label text="String Field: {o.s}" />
    </mx:Application>
    
    
    package
    {
        public class TestObject
        {
            [Bindable]
            public var n:Number;
            [Bindable]
            public var s:String; 
    
            public function TestObject()
            {
                trace("Initialized test object ...", n, s);
            }
        }
    }
    

    【讨论】:

    • 是的,我把断点放在那里。这就是为什么它没有工作?如果我之前在 mxml 标签附近设置断点会有帮助吗?
    • 可能不会。如果您想在设置这些变量后立即运行代码,您应该考虑使用 getter 和 setter 方法来处理它们。
    • 所以,据我了解,变量没有在构造函数中初始化,如果需要变量,从构造函数调用方法来做某事是没有意义的?在这种情况下什么时候调用它?
    • 无论是从您正在使用的方法的设置器中,还是在显示对象上,使用 creationComplete 处理程序。
    • 刚刚意识到我需要上面提到的用户变量,而不是在构造函数中,而是在创建完成时
    【解决方案2】:

    只是为了详细说明 Dan Monego 的答案和 cmets。将类更改为类似于下面的类。然后就可以在set函数上设置断点了。

    public class Board extends Canvas
    {
            private var _boardSize:Number;
    
            public function get boardSize():Number{
               return _boardSize;
            }
    
    
            public function set boardSize(val:Number):Void{
               _boardSize = val;
            }
    
            private var cellWidth:Number;
            public function Board()
            {
                    super();
    
            }
    }
    

    【讨论】:

    • 函数集 boardSize 应该输入 :void
    【解决方案3】:

    试试这个:

    <MyComp:Board x="22" y="25" width="600" height="600" boardSize="{Number(19)}">
    

    或者这个:

    <mx:Script>
    <![CDATA[
    public var boardSize:Number = 19;
    ]]>
    </mx:Script>
    
    <MyComp:Board x="22" y="25" width="600" height="600" boardSize="{boardSize}">
    

    问题可能是您将它作为字符串传递给组件,它没有意识到它是一个数字。

    【讨论】:

      【解决方案4】:

      我认为要获得 mxml 代码完成,您需要在所需的属性上方添加 [Inspectable] 元标记。

      [Inspectable(defaultValue="", type="Number", name="boardSize", format="Number")]
      public var boardSize:Number;
      

      试试这个,让我知道你的进展如何。加载有关此类组件开发的更多信息here

      【讨论】:

      • inspectable 标签让您可以控制自动完成的工作方式(例如,将一个字段限制为几个输入),但所有公共属性默认显示在自动完成中。
      【解决方案5】:

      如果您查看构造函数,它没有参数,因此您需要属性或公共变量来设置值。如果您想使用参数创建自定义组件,则必须创建一个不同的构造函数,如下所示。不要认为可以使用 mxml 中的 args 调用构造函数,但使用 actionScript 您可以使用可选参数来设置值...

      public class Board extends Canvas
      {
              public var boardSize:Number;
              private var cellWidth:Number;
              public function Board(boardSize:Number = 0, cellWidth:Number = 0)
              {
                      super();
                      this.boardSize = boardSize;
                      this.cellWidth = cellWidth;
      
      
              }
      }
      

      【讨论】:

        【解决方案6】:

        您最可能希望访问此属性的地方是在设置组件和创建其子组件期间 - 因为“creationComplete”应该已经在您完成之后:) 为此,请覆盖 createChildren() 方法。此外,您可能还想为它创建一个 setter(或至少绑定到它)以捕获更改。

        例子:

        package {
          import flash.events.Event;
        
          public class Board extends Canvas {
        
          /** clever ASDoc comment goes here */
          [Bindable("boardSizeChanged")]
          [Inspectable(category="General", defaultValue="")]
          var _boardSize: Number;
          public function get boardSize(): Number {
              return _boardSize;
          }
          public function set boardSize(value: Number): void {
              if (_boardSize == value) return;
              _boardSize = value;
              // do something when boardSize changes, e.g. update child components
              trace("Boardsize is now: " + value);
              dispatchEvent(new Event("boardSizeChanged"));
          }
        
          public function Board() {
              super();
          }
        
          override protected function createChildren(): void {
              super.createChildren();
              // create your own children, using the boardSize property (this uses the getter function)
              trace("Boardsize: " + boardSize);
          }
        }}
        

        请注意,在此示例中,set boardSize() 在 createChildren 之前调用 - 因此,如果您使用 boardSize 更改您的孩子,您应该确保他们确实已经存在于这个 setter 中。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-12-06
          • 1970-01-01
          • 1970-01-01
          • 2021-12-28
          • 1970-01-01
          相关资源
          最近更新 更多