1

作成中の Flex アプリで問題が発生しています。問題は、コンポーネントのライフサイクルに対する私の理解不足にあると思います。いくつかの指針をいただければ幸いです。

私のアプリは Air で動作します。アプリケーションは、DashItems の配列を作成します。DashItem は、Canvas を拡張する ActionScript クラスです。DashItem の作成時に渡されたデータに基づいて、さまざまなコンポーネントがこのキャンバスに追加されます。たとえば、dashtype が「grid」の場合、EvGrid が作成されます。EvGrid は、DataGrid に基づく mxml コンポーネントです。DashItem は URL を設定し、HTTPService send() を開始する EvGrid のパブリック関数を呼び出します。データが取得され、グリッドに表示されます。これは期待どおりに機能しています。

ここがトリッキーな部分です。これらの DashItems (Snackr を考えてください) のスクロール表示を行いたいと考えています。そこで、メインアプリケーションで Event.ENTER_FRAME のイベントリスナーを設定しました。呼び出された関数は、アイテムを画面の上にスクロールし、上にスクロールするとリサイクルします。DashItems の配列を作成した直後にこの eventListener を作成すると、何も表示されません。デバッグ DashItems 内のコンポーネントが HTTPService からデータを受信して​​いることがわかります。また、スクロール コードが y 設定を調整していることがわかりますが、アプリケーション ウィンドウには何も表示されません。

完了時に ENTER_FRAME イベント ハンドラーを設定する別のタイマーを設定して、ENTER_FRAME の eventListener の追加を遅らせると、アイテムが表示されます。ただし、dataService の戻りが遅い場合は、空のグリッドが表示されることがあります。グリッド データ プロバイダはバインド可能です。

これにより、コンポーネントのライフサイクルの一部を踏みにじっていると思います。以下にいくつかのコードスニペットを配置します。この初心者への助けやアドバイスをありがとう。

mx:Script セクションの Scroller.mxml

public function handleApplicationComplete(event:Event):void {
                dataService.send();
            }
            public function faultHandler(event:FaultEvent): void {
                trace(event.toString());
            }

            public function resultHandler(event:ResultEvent): void {
                trace("returned XML: " + event.result.toString());
                for each (var i:XML in event.result.item) {
                    var dx:DashItem = new DashItem({
                                        type:   i.type,
                                        url:    i.url.toString(),
                                        index:  i.index,
                                        title:  i.title,
                                        description: i.description,
                                        height: this.height/(DISPLAY_LIST_SIZE -1),
                                        width:  this.width * 0.9
                                    });

                    trace("created " + dx.toString());
                    DashList.unshift(dx);
                }
                buildDisplayList();
                var timer:Timer = new Timer(1000, 1);
                timer.addEventListener(TimerEvent.TIMER_COMPLETE, startAnimation);
                timer.start();
            }

            private function startAnimation(event:TimerEvent):void {
                trace("starting animation");
                addEventListener(Event.ENTER_FRAME, animate);   
            }

            private function buildDisplayList():void {
                var starty:Number = this.height;
                var listSize:Number = DISPLAY_LIST_SIZE;
                if ( DashList.length < DISPLAY_LIST_SIZE) {
                    listSize = DashList.length;
                }
                for (var i:Number = 0; i < listSize; i++) {
                    var di:DashItem = DashList.pop();
                    displayList.unshift(di);
                    di.y = starty;
                    scroller.addChild(di);
                    starty += di.height + PADDING;
                }
                trace("DisplayList is: ");
                traceList(displayList);
            }

スクローラーの HTTPService:

<mx:HTTPService
        id="dataService"
        url="{DS_URL}"
        resultFormat="e4x"
        fault="faultHandler(event);"
        result="resultHandler(event);" />

DashItem.as スニペット

public function build():void {
            if (type == "grid") {
                trace("Building EventList...");
                var ev:EvGrid = new EvGrid();
                ev.evtitle = this.title;
                this.addChild(ev);
                ev.fetchData();
            } else if (type == "StatChart") {

EvGrid スニペット:

<mx:HTTPService 
        id="dataService"
        url="{ws}"
        resultFormat="e4x"
        result="resultsHandler(event);"
        fault="faultHandler(event);"
    />  

    <mx:XMLListCollection id="eventListXml" source="{xmlData.events.event}"/>
    <mx:Panel id="evwrapper" title="{evtitle}" width="100%" height="100%">

    <components:RowColorDataGrid id="EventListGrid"
            dataProvider="{eventListXml}"
            width="100%"
            height="100%"
            rowCount="{eventListXml.length+1}"
            rowColorFunction="calcRowColor">
            <components:columns>
                <mx:DataGridColumn 
                    id="Serial"
                    dataField="serial"
                    headerText="Serial"
                    width="70"

                />
                <mx:DataGridColumn 
                    id="Severity"
                    dataField="severity"
                    headerText="Severity"
                    width="60"
                />
                <mx:DataGridColumn
                    id="snlStatus"
                    dataField="snlstatus"
                    headerText="snlStatus"
                    width="100"
                />
                <mx:DataGridColumn
                    id="Owneruid"
                    dataField="owneruid"
                    headerText="Owner"
                    width="70"
                />
                <mx:DataGridColumn
                    id="Node"
                    dataField="node"
                    headerText="Node"
                    width="120"
                />
                <mx:DataGridColumn
                    id="Summary"
                    dataField="summary"
                    headerText="Summary"
                    labelFunction="getCdata"
                />
            </components:columns>
        </components:RowColorDataGrid>

    </mx:Panel

>

4

3 に答える 3

1

問題は、コンポーネントのライフサイクルについての理解が不十分であることにあると思います。いくつかの指針をいただければ幸いです。

Flexコンポーネントのライフサイクルに関する優れたホワイトペーパー。特に問題に対処しているわけではありませんが、ライフサイクルに関する知識が必要な場合は、これで対応できます。

于 2009-08-25T04:55:43.737 に答える
0

1、2年前のMAXでのDeepaのプレゼンテーションは、Flexコンポーネントのライフサイクルをよりよく理解するための優れた方法です。

http://tv.adobe.com/MAX-2008-Develop/Creating-New-Components-in-Flex-3-by-Deepa-Subramaniam.html#vi+f15384v1002

プロパティ、サイズ、表示リストの無効化スキームを理解すると、実行できる量は膨大になります。

于 2009-08-25T23:11:52.600 に答える
0
  1. setTimeout(startAnimation, 1000) を呼び出します。おそらくタイマーを作成するよりも簡単です。または、UIComponents で「callLater」関数を使用するだけです。

  2. 同じことに注意してください... ENTER_FRAME の代わりに setInterval(func, 33) を使用できます (約 30 フレーム/秒と仮定)。

  3. アイテムの準備が整ったことを確認するには、FlexEvent.CREATION_COMPLETE イベントをリッスンします。

于 2009-08-25T04:33:08.730 に答える