1

Q を説明するために、例を単純化しすぎます (実際には、コードはもっと複雑です)。

下にデータグリッドを含むフレックスコントロールがあるとします。何かのようなもの

<mx:DataGrid id="grid" dataProvider="{document.items}">
    <mx:columns>
        <mx:DataGridColumn headerText="Column 1" dataField="@name"/>
        <mx:DataGridColumn headerText="Column 2" dataField="@value"/>
    </mx:columns>
</mx:DataGrid>

document は、いくつかのデータを含む Model オブジェクトです。クライアントは基になるデータモデルについて何も知りたくないので、コントロールに選択セッターを提供します。

public function set selectedItem(title:String):Allocation
{
   grid.selectedItem  = null;

   for each(var o:Object in grid.dataProvider)
   {
      var t:String = o.@title;
      if( t == title )
      {
         grid.selectedItem = o;
         return;
      }
   }
}

ここまでは順調ですね。document.items が事前入力されている場合、選択は正しく機能します。でも。アプリケーションの起動時に、何を選択すべきかが既にわかっている場合はどうすればよいでしょうか? たとえば、URL で渡されているのでしょうか? したがって、フレックスでは次のようなものがあるかもしれません

// Initialising now...
mycontrol.document = this.document; // give the control the document

// Fetch titles
new FetchTitlesEvent().dispatch(); // cairngorm-style event

// Set the selection 
mycontrol.selectedItem = Application.application.parameters.title;

おっと。FetchTitlesEvent は非同期で動作するため、その時点で mycontrol.selectedItem は機能しません。どういうわけか、そのコードを (再) トリガーして、コントロールに選択を設定する必要があります。さて、これを行うにはいくつかの方法が考えられますが、すべてコードのにおいがします。

1) フェッチが完了した後、FetchTitlesCommand で実行します。これにより、これを知る必要があるビュー (またはビューs ) の知識でコマンドが汚染されます。メンテナンスの悪夢が待っているように感じます。つまり、ビューは完全にコマンドにバインドされており、それらのコマンドは再利用できません。ブリーチ。

2) 完了時にイベントからコールバックを取得します (FetchTitlesEvent で開始し、セットを実行する新しいコマンドで終了する複合コマンドを作成します)。私には壊れやすいようです-メンテナーはどのコールバックが必要であるかをどのように知るのですか? また、UI コントロールの知識をコマンドにバインドしています。不良。

3) ある種のタイマーを用意して、イベント キューが数秒間静止するのを待ちます。ハクシティハック。

4)コントロールでそれを行います。document.items の mycontrol で collectionevents にバインドし、変更を監視します。選択に一致する行が到着したら、それを選択し、変更の監視を停止します。- コントロールはそれを行うのに適した場所を感じます - コレクションイベントはエキサイティングな CHANGE または REFRESH イベントをスローすることがあります - 横たわっている高価なモニターのようです

私はかなり(4)に傾いています。この問題をトラップするためにフレクサーが以前に使用した他のオプションはありますか?

4

4 に答える 4

2

selectedItemコントロールのプロパティを Bindable Object 変数に設定できます。

<mx:Script>
    <![CDATA[
        [Bindable]
        private var mySelectedItem:Object;
    ]]>
</mx:Script>

<mx:DataGrid id="grid" dataProvider="{document.items}" selectedItem="{mySelectedItem}">
    <mx:columns>
        <mx:DataGridColumn headerText="Column 1" dataField="@name"/>
        <mx:DataGridColumn headerText="Column 2" dataField="@value"/>
    </mx:columns>
</mx:DataGrid>

この方法でいつでも selectedItem を設定またはリセットでき、コントロールはオブジェクトに基づいて selectedItem を更新します。たとえば、initialize イベント、creationComplete イベント、またはその他の関数のハンドラーで設定できます。変数を設定するとき、または初期化中に変数を設定する場合はコントロールの creationComplete で、validateNow() を呼び出す必要がある場合があります。

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" initialize="initializeHandler();">
    <mx:Script>
        <![CDATA[
            [Bindable]
            private var mySelectedItem:Object;

            private function initializeHandler():void
            {
                mySelectedItem = getSelectedItem(); // your logic to determine the initial item to select
            }

            ....

            private function grid_creationCompleteHandler():void
            {
                grid.validateNow();
            }
        ]]>
    </mx:Script>

    <mx:DataGrid id="grid" dataProvider="{document.items}" selectedItem="{mySelectedItem}" creationComplete="grid_creationCompleteHandler();">
        <mx:columns>
            <mx:DataGridColumn headerText="Column 1" dataField="@name"/>
            <mx:DataGridColumn headerText="Column 2" dataField="@value"/>
        </mx:columns>
    </mx:DataGrid>
</mx:Application>
于 2009-03-26T14:44:42.453 に答える
1

これを行う正しい方法は、あなたの質問を正しく理解している場合は、creationCompleteイベントを使用することです。flexのすべてのUIオブジェクトは、すべてが完了して準備ができたことを通知するcreationCompleteイベントをブロードキャストします。グリッド自体でcreationCompleteイベントをリッスンするか、すべての子(すべて)が作成されるまでブロードキャストされないため、アプリケーションでリッスンできます。

于 2009-03-26T12:44:08.547 に答える
0

残念ながら、これは作成完了の問題ではありません。問題はコントロールの初期化ではなく、データの初期化です。非同期であるため、最終的にいつ到着するかはわかりません。

于 2009-03-26T12:55:36.427 に答える
0

ChangeWatcher を使ってみる

var cw:ChangeWatcher = ChangeWather.watch(this, ["document","items"], 
function(e:Event):void
{
    //check to see if the data we want to select has arrived

    //once we've selected the data, we don't need this handler anymore
    cw.unwatch();
});

構文上のバグはご容赦ください。目の前に FB はありません。

于 2009-03-31T02:22:17.610 に答える