Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   ActionScript 3.0 (http://www.flasher.ru/forum/forumdisplay.php?f=83)
-   -   как создать SWC реагирующий на [Bindable] масив ? (http://www.flasher.ru/forum/showthread.php?t=129199)

adi.belis 26.08.2009 22:44

как создать SWC реагирующий на [Bindable] масив ?
 
всем привет .

я написал класс который должен апдаитить свою дату в зависимости от изменения источника.
Код AS3:

package com
{
        import mx.flash.UIMovieClip;
 
        public class TestComponent extends UIMovieClip
        {
                private var myArray:Array;
                public function TestComponent ()
                {
 
                }
                [Inspectable(category = Data,type = "Array")]
                public function set DataProvider (arr:Array):void
                {
                        this.myArray = arr;
                        textFild.text =String(myArray.length);
                }
        }
}

из него создаем компонент ,засовываем в Flex, добавляем массив :
Код AS3:

<fx:Script>
        <![CDATA[
 
          [Bindable]
          private var array:Array;
 
          protected function initApps(event:FlexEvent):void
        {
          array = new Array();
          array.push("a")
          array.push("b")
          array.push("c")
          }
          ]]>
        </fx:Script>
<com:TestComponent id="tc"  DataProvider="{array}"/>

старт и... :(
в общем не работает привязка .

как мне это починить ?

udaaff 26.08.2009 22:53

ArrayCollection используйте.

adi.belis 27.08.2009 00:48

компонент создан на Flash(SWC) , чтоб я мог им управлять в Flax я вставил мета тег :

Код AS3:

[Inspectable(category = Data,type = "Array")]
                public function set DataProvider (arr:Array):void
                {...

у него в типе нет поддержки ArrayCollection .

wvxvw 27.08.2009 02:36

Inspectable - поддерживается флешевым компилятором, Bindable - нет.

adi.belis 27.08.2009 03:41

другими словами компонент созданий на Flash не сможет никак апдейтится через Bindable ?

wvxvw 27.08.2009 04:54

Неа, не будет, да и забиндить к массиву тяжело, т.как он не IEventDispatcher :) Как возможное решение - Создайте пустой класс mx.collections.ArrayCollection с теми же свойствами и методами, что есть у настоящей ArrayCollection + посмотрите, от чего он там зависит, добавьте его в класс-путь флеша и назначте его как тип дата-провайдеру (при этом не забывайте писать свойства и методы с маленькой буквы). После чего, импортируйте етот "недокомпонент" во флексовый проект, отнаследуйтесь от него, и в классе-наследнике переопределите это свойство + добавьте метатаг.
Кроме того, если это сеттер а не просто переменная, то сеттеры биндятся не так, а примерно так:
Код AS3:

[Bindable("dataProviderChange")]
public override function set dataProvider(value:ArrayCollection):void
{
// setter's code
dispatchEvent(new Event("dataProviderChange"));
}


adi.belis 27.08.2009 19:08

Цитата:

Создайте пустой класс mx.collections.ArrayCollection с теми же свойствами и методами, что есть у настоящей ArrayCollection
создаю (котаю с флекса) :

Код AS3:

package mx.collections
{
 
import flash.utils.IDataInput;
import flash.utils.IDataOutput;
import flash.utils.IExternalizable;
import mx.core.mx_internal;
 
use namespace mx_internal;
 
[DefaultProperty("source")]
 
[RemoteClass(alias="flex.messaging.io.ArrayCollection")]
 
 
public class ArrayCollection extends ListCollectionView implements IExternalizable
{
    include "../core/Version.as";
 
 
    public function ArrayCollection(source:Array = null)
    {
        super();
 
        this.source = source;
    }
 
 
    [Inspectable(category="General", arrayType="Object")]
    [Bindable("listChanged")] //superclass will fire this
 
 
    public function get source():Array
    {
        if (list && (list is ArrayList))
        {
            return ArrayList(list).source;
        }
        return null;
    }
 
    public function set source(s:Array):void
    {
        list = new ArrayList(s);
    }
 
    public function readExternal(input:IDataInput):void
    {
        if (list is IExternalizable)
            IExternalizable(list).readExternal(input);
        else
            source = input.readObject() as Array;
    }
 
    public function writeExternal(output:IDataOutput):void
    {
        if (list is IExternalizable)
            IExternalizable(list).writeExternal(output);
        else
            output.writeObject(source);
    }
 
}
 
}

1.
Код:

[DefaultProperty("source")]
[RemoteClass(alias="flex.messaging.io.ArrayCollection")]

эти мета теги вроде не поддерживаются флешом,

2.
Код:

ArrayCollection extends ListCollectionView
что делать с ListCollectionView он тоже не класс флеша;
В общем не совсем понятно, как его изменить ?

и еще такой вопрос, в флексовском компоненте "ComboBox" к "dataProvider" можно подключать обычный массив и апдеит работает, чем это отличается от моего компонента ?

wvxvw 28.08.2009 01:07

ОК, сначала простое:
когда вы подключаете массив в качестве датапровайдера компонент его сам обворачивает в ArrayCollection, но лучше это делать самому - вам же в итоге удобнее будет.

>> эти мета теги вроде не поддерживаются флешом,
это уже добавьте в компоненте, который будет экстендить ваш компонент во флексе, флекс "догадается" заменить ваш "поддельный" ArrayCollection своим, если вы ему не будете кормить свой. Вам не нужно имплементить методы ArrayCollection, просто создайте intrinsic класс, т.е. с пустыми методами / свойствами - вы же его все равно в окончательном проекте использовать не будете.

>> ArrayCollection extends ListCollectionView
Это по-серьезнее проблема, но тоже решаемая, т.е. прийдется соответственно создать ListCollectionView и его суперкласс (всех до Proxy), чтобы описание класса совпало с флексовым, хотя, можно попробовать ни от чего не наследоваться - а вдруг прокатит? :)

adi.belis 28.08.2009 01:14

Цитата:

Как возможное решение - Создайте пустой класс mx.collections.ArrayCollection с теми же свойствами и методами
в общем не работает отпишу попорядку


/**
*создаю "ArrayCollection" для Флеша
*/

1.1 создаю в флексе "Flex Library Project".
1.2 в библиотеке "src" создаю свой класс "ArrCollection ".
1.3 пишу код :
Код AS3:

package
{
        import mx.collections.ArrayCollection;
 
        public class ArrCollection
        {
                public function ArrCollection()
                {
                        new ArrayCollection();
                }
        }
}

1.4 сохраняем, в папке Bin лежит готовый ArrayCollection.swc

/**
*добавляю "ArrayCollection" в Флеш
*/
2.1 в Флеш Publish settings > flash >Script > settings > Library Path
добавляю ArrayCollection.swc .

/**
*создаю компонент для Флекса
* в компоненте имеется textFild для отображения длины коллекции массивов.
*/

3.1 в Флаш добавляю новый объект, его код :
Код AS3:

package com
{
        import mx.flash.UIMovieClip;
        import mx.collections.ArrayCollection;
 
        public class TestComponent extends UIMovieClip
        {
                protected var myArray:ArrayCollection;
                public function TestComponent ()
                {
 
                }
                [Inspectable(category = Data,type = "Array")]
                public function set dataProvider (arr:ArrayCollection):void
                {
                        myArray = arr;
                        textFild.text =String(myArray.length);
                }
        }
}

3.2 делаю из него SWC файл (command > Convert Symbol to Flex Component > publish)

/**
*наследую и переопределяю
*/

4.1 в Флекс в "Libs" добавляю мой компонент "TestComponent.swc".
4.2 создаю новый класс, наследую от "TestComponent.swc", переопределяю функцию.
Код AS3:

package com
{
        import flash.events.Event;
        import mx.collections.ArrayCollection;
 
        public class SuperComponent extends TestComponent
        {
            public function SuperComponent ()
            {
            }
            [Bindable("dataProviderChange")]
            public override function set dataProvider(value:ArrayCollection):void
                      {
                myArray = value;
                textFild.text =String(myArray.length);
                dispatchEvent(new Event("dataProviderChange"));
                      }
        }
}

вроде-бы все по инструкции .
проверяю в Флексе :

Код:

<?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/halo" 
        width="400" height="300" creationComplete="initApps(event)" xmlns:com="com.*">
        <fx:Script>
                <![CDATA[
                        import com.customTest;
                        import mx.collections.ArrayCollection;
                        import mx.events.FlexEvent;

            [Bindable]
                        private var tempArray:ArrayCollection =new ArrayCollection();
                        protected function initApps(event:FlexEvent):void
                        {
                                tempArray.addItem("La-la");
                        }
                ]]>
        </fx:Script>
        <mx:Label x="23" y="33" text="Label" id="_label"/>
        <com:customTest id="yo" x="28" y="57" dataProvider="{tempArray}" />
</s:Group>

получаю значение 0 не апдейтится :(

wvxvw 28.08.2009 01:37

Нее... не так... ладно, ждите, сделаю пример :)


Часовой пояс GMT +4, время: 13:09.

Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.