Flex / ActionScript3 - Атрибут объекта / Переменная null - PullRequest
1 голос
/ 06 января 2011

Если я выполняю приведенный ниже код в FlashBuilder, я получаю следующую ошибку (я перевожу ее)

TypeError: Error #1009: Access to an Attribute or Method of an null-Object is not possible.
 at components::NumDisplay()[\src\components\NumDisplay.mxml:39]

Эта строка в NumDisplay.mxml является проблемой:

[Bindable]
public var oneled_top:OneDisplay = new OneDisplay(numberData.led_top);

Если я изменю его с вышеприведенного на:

[Bindable]
public var oneled_top:OneDisplay = new OneDisplay(1);

Это работает, потому что я посылаю реальный номер.Так как я могу получить доступ к значению numberData.led_top ?

Если я проверяю доступ в том же файле NumDisplay.mxml со строкой

<s:Label text="{numberData.led_top}" color="#FF0000">
</s:Label>

, он получает доступ к значению так же, как если бы я поместил его в свой компонент

<components:oneLedDisplay showData="{numberData.led_top}" x="10" y="10" />

Я не получаю его после нескольких часов поиска ... Заранее спасибо.

Мой основной метод tasachenrechner.mxml :

<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
      xmlns:s="library://ns.adobe.com/flex/spark" 
      xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="600" minHeight="500" xmlns:components="components.*">
 <fx:Script>
            <![CDATA[
   import components.NumberDisplay;
   [Bindable]
   protected var firstNumber:NumberDisplay = new NumberDisplay(1);
   [Bindable]
   protected var secondNumber:NumberDisplay = new NumberDisplay(2);
             ]]>
 </fx:Script>

 <components:NumDisplay
  numberData="{firstNumber}"
  x="10" 
  y="20"/>

 <components:NumDisplay 
  numberData="{secondNumber}"
  x="73" 
  y="20"/>

</s:Application>

Мой класс AS NumberDisplay.as :

package components
{
 import flash.display.DisplayObject;

 [Bindable]
 public class NumberDisplay
 {
  public var num:Number;

  public var led_top:Number=0;
  public var led_r1:Number=0;
  public var led_r2:Number=0;
  public var led_middle:Number=0;
  public var led_l1:Number=0;
  public var led_l2:Number=0;
  public var led_bottom:Number=0;

  public function NumberDisplay(num:Number)
  {
   this.num = num;
   switch(this.num)
   {
    case 0:
     trace("ZERo");
     break;
    case 1:
     led_top = 1;
     led_r1 = 1;
     led_r2 = 1
     trace("EINS" + led_top + " num:" + num);
     break;
                            //[... some more cases]
    default:
     break;
   }
  }
 }
}

Мой NumDisplay.mxml :

<?xml version="1.0" encoding="utf-8"?>
<s:Group xmlns:fx="http://ns.adobe.com/mxml/2009" 
   xmlns:s="library://ns.adobe.com/flex/spark" 
   xmlns:mx="library://ns.adobe.com/flex/mx" width="45" height="59"
   xmlns:components="components.*">

 <fx:Style>
  @namespace s "library://ns.adobe.com/flex/spark";
  @namespace mx "library://ns.adobe.com/flex/mx";
  @namespace components "components.*";
 </fx:Style>

 <fx:Script>
  <![CDATA[
   import components.NumberDisplay;
   import components.OneDisplay;

   [Bindable]
   public var numberData:NumberDisplay;

   [Bindable]
   public var oneled_top:OneDisplay = new OneDisplay(numberData.led_top);
                        // some more init calls of data-objects same type
  ]]>
 </fx:Script>


 <s:Label text="{numberData.led_top}" color="#FF0000">
 </s:Label>

 <components:oneLedDisplay showData="{oneled_top}" x="10" y="10" />
        // some more objects of same type
</s:Group>

МойAS-Class OneDisplay.as :

package components
{
 import flash.display.DisplayObject;

 public class OneDisplay
 {
  [Bindable]
  public var show:Number;
  [Bindable]
  public var value:Number=0;

  public function OneDisplay(show:Number)
  {
   this.show = show;
   switch(this.show) 
   {
    case 0:
     value = 0.3;
     trace(value);
     break;
    case 1:
     value = 1.0;
     trace(value);
     break;
   }
  }
 }
}

My oneLedDisplay.mxml :

<?xml version="1.0" encoding="utf-8"?>
<s:Group xmlns:fx="http://ns.adobe.com/mxml/2009" 
   xmlns:s="library://ns.adobe.com/flex/spark" 
   xmlns:mx="library://ns.adobe.com/flex/mx">
 <fx:Script>
  <![CDATA[
   import components.OneDisplay;
   [Bindable]
   public var showData:OneDisplay;
  ]]>
 </fx:Script>

 <s:Rect id="stroke" width="40" height="6" alpha="{showData.value}">
  <s:fill>
   <s:SolidColor color="#000000"/>
  </s:fill>
 </s:Rect>

 <s:Label text="{showData.value}" color="#FF0000">
 </s:Label>

</s:Group>

Ответы [ 3 ]

4 голосов
/ 06 января 2011

Помните, что вы не только присваиваете значение, но объявляете переменную-член oneled_top. В этот момент вы не можете получить доступ к numberData, потому что он не был создан (нет вызова на new NumberData()! Вам нужно найти способ позвонить на new OneDisplay (numberData.led_top) позже, когда на самом деле значение для доступа.

2 голосов
/ 06 января 2011

Вы предоставили много кода, который я не хочу перепроектировать.

Ответ заключается в том, что oneled_top инициализируется перед numberData. Вы не можете контролировать инициализацию переменных при использовании MXML.

Установите значения по умолчанию в методе commitProperties (), или, если oneled_Top предполагается частью скина, установите значения по умолчанию в методе PartAdded.

Вы извлечете пользу из чтения о жизненном цикле компонентов .

0 голосов
/ 23 февраля 2011

Вы можете использовать BindingUtils.bindSetter() для обнаружения изменений в numberData и затем инициализировать oneled_top

BindingUtils.bindSetter(_setOneLabel_top, this, "numberData");

и сеттер:

function _setOneLabel_top(disp:NumberDisplay):void
{
  /* if(this.oneled_top == null) */
  this.oneled_top = new OneDisplay(disp.led_top);
}

Но я думаю, что вы используете [Bindable] там, где вам это не нужно.

...