2012-01-30 2 views
5

У меня есть пользовательский компонент Flex 4+, который я пытаюсь сделать, и чтобы скин знал об изменениях в настраиваемом свойстве. Это свойство будет определять графику на кнопке (и некоторые другие визуальные изменения), но данные будут постоянно меняться, поскольку они будут обновляться таймером.Flex 4 Custom Component - Как уведомить скин об изменениях свойств?

Я рассмотрел невыразимые примеры и по-прежнему кажется неспособным получить синтаксис правильно или обнаружить, как вещи должны быть разделены. Я смотрел на отмену commitProperties и PropertyChangeEvent без успеха. Поэтому у меня есть два вопроса.

1) Как я могу получить скин, который будет уведомлен об связанном имуществе, когда он изменится?

2) Если данные для связанного свойства компонента являются объектами, они будут работать надлежащим образом, если свойство объекта изменится (или было бы лучше передать каждое свойство отдельно)?

Вот урезанный пример того, чего я пытаюсь достичь.

компонент выглядит следующим образом:

<s:ButtonBase 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[ 
     private var _iconData:String; 

     [Bindable] 
     public function get iconData():String 
     { 
      return _iconData; 
     } 
     public function set iconData(value:String):void 
     { 
      _iconData = value; 
     } 
    ]]> 
</fx:Script> 

Я звоню это так:

<components:MyButton id="myButton" iconData="{myData.curIconTag}" skinClass="skins.MyButtonSkin" /> 

У меня есть много различных изображений, которые я мог бы быть погрузочных и поэтому я Я боюсь, что количество состояний (с комбинациями вверх/вниз/выше/отключено и т. д. может выйти из-под контроля, поэтому SetIconDisplay устанавливает значок, но реальный ключ заключается в том, что у меня есть другой код в этой функции который должен выполняться, когда свойство iconData изменяется каждые X минут или около того. Таким образом, кожа что-то вроде этого:

<s:Skin xmlns:fx="http://ns.adobe.com/mxml/2009" 
    xmlns:s="library://ns.adobe.com/flex/spark" 
    xmlns:fb="http://ns.adobe.com/flashbuilder/2009" 
    creationComplete="init()"> 

<fx:Metadata> 
    [HostComponent("components.MyButton")] 
</fx:Metadata> 

<s:states> 
    <s:State name="default" /> 
    <s:State name="down"/> 
    <s:State name="up"/> 
    <s:State name="over"/> 
    <s:State name="disabled" /> 
</s:states> 

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

     [Embed(source="images/image1.png")] 
     private var icon1:Class; 

     [Embed(source="images/image2.png")] 
     private var icon2:Class; 

     [Embed(source="images/image3.png")] 
     private var icon3:Class; 

     [Bindable] 
     public var hostComponent:MyButton; 

     [Bindable] 
     private var iconClass:Class; 

     private function init():void 
     { 
      iconClass = new Class(); 
     } 

     // how do I get this called when the iconData property on my custom component is changed? 
     private function SetIconDisplay():void 
     { 
      switch (hostComponent.iconData) 
      { 
       case "apple": 
        iconClass=icon1; 
        break; 
       case "orange": 
        iconClass=icon2; 
        break; 
       case "grape": 
        iconClass=icon3; 
        break; 
      } 
     } 
    ]]>   
</fx:Script> 

<s:BitmapImage source="{iconClass}" x="0" y="0" width="180" height="108"/> 

Опять же, не волнуйтесь так много о том, как кожа на самом деле делает то, что он делает, как, вероятно, изменится (не используя состояния). Я просто пытаюсь выяснить, как вызвать определенную функцию при изменении свойства bound.

Спасибо!

ответ

0
<s:BitmapImage source="{hostComponent.iconClass}" /> 

должен работать


вам не нужно объявлять общественности hostComponent Var: MyButton;

это часть SparkSkin

+1

Посмотрите на код SparkSkin, и вы увидите, что hostComponent не является частью SparkSkin. Я считаю, что свойство создается во время компиляции на основе метаданных компонента хоста. Это имеет смысл, потому что все оболочки MXML расширяют SparkSkin и этот скин не имеет возможности узнать, что должен быть тип аргумента свойства hostComponent. На скине ActionScript вы должны вручную создать свойство hostComponent. – JeffryHouser

3

Имея базовый класс вызова функции на одной конкретной коже может получить неудобно, так как это означает, что базовый класс зависит от класса кожи, что делает его трудно поменять скин , Есть два хороших способа обойти это:

Вариант 1: Переместите iconClass в компонент. Класс skin может напрямую связываться с этим свойством, а логика решения, какой значок использовать, может обрабатываться компонентом вместо скина. Это сохраняет логику из-за кожи и сохраняет код скиннинга, с которым вы должны работать.

Вариант 2: Добавить свойство iconData на скин и привязать его к свойству iconData компонента хоста. В функции setter вызовите SetIconDisplay, когда у вас есть допустимое значение. Это сохраняет значки, инкапсулированные в скин, что может помочь, если вы хотите использовать совершенно другой скин для одного и того же компонента.

Редактировать: Если вы планируете создать несколько других скинов, которые не используют значки, # 2 - путь. Создайте свойство на коже выглядеть примерно так:

private var _iconData:String; 

public function get iconData():String 
{ 
    return _iconData; 
} 

public function set iconData(value:String):void 
{ 
    _iconData = value; 
    SetIconDisplay() 
} 

Затем используйте привязки для подключения его к hostComponent:

<fx:Binding source="hostComponent.iconData" destination="iconData" /> 
+0

Пользовательский компонент очень простой, но у меня будет около 4 или 5 различных скинов для него. Этот особый скин отличается тем, что он может иметь одну из многих разных значков, некоторые анимации и другие уникальные вещи, но я боролся с тем, что является «лучшей» практикой для логики. Логика в коже, казалось, имела смысл, потому что именно код определяет, что отображать. Код в компоненте, похоже, не имеет смысла, потому что я думал, что сам компонент не должен знать или заботиться о том, как он выглядит. Он просто хочет добавить свойство для скина, чтобы определить, что делать. – ImAStreamer

+0

@ImAStreamer Похоже, вы должны взять второй подход и обновить скин, чтобы получить свойство iconData. Я обновил ответ с требуемым кодом. –

+0

Мне нравится этот второй подход. Я нашел другой подход, который работает. Не уверен, что было бы предпочтительнее. См. Мой ответ на мой вопрос. – ImAStreamer

5

Я в конечном итоге диспетчерская пользовательское событие, когда данные обновляются и прислушиваться к нему в коже.

Компонент:

<s:ButtonBase 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 classes.CustomEvent; 

      private var _iconData:String; 

      [Bindable] 
      public function get iconData():String 
      { 
       return _iconData; 
      } 
      public function set iconData(value:String):void 
      { 
       _iconData = value; 
       dispatchEvent(new CustomEvent("iconDataUpdated")); 
      } 
     ]]> 
</fx:Script> 

Кожа добавляет это:

protected function skin_preinitializeHandler(event:FlexEvent):void 
{ 
     hostComponent.addEventListener(CustomEvent.ICON_DATA_UPDATED,SetIconDisplay); 
} 
+0

хороший один помощник, я думаю, что это путь, потому что если вы посмотрите на SparkButtonSkin, то есть следующий код: общественная функция, заданная hostComponent (значение: ButtonBase): аннулируются { если (_hostComponent) _hostComponent.removeEventListener (» contentChange ", contentChangeHandler); _hostComponent = значение; if (value) _hostComponent.addEventListener ("contentChange", contentChangeHandler); } – zavr

1

Другим решением общего вопроса, хотя, возможно, не идеально в этой ситуации, это вызвать кожу. invalidateDisplayList() всякий раз, когда изменяется свойство. Затем в скине переопределите функцию updateDisplayList и оттуда вызовите функцию, которая реагирует на измененные свойства, а также вызовет функцию родительского класса.

Смотрите здесь: https://forums.adobe.com/thread/797247

Смежные вопросы