標準の HTTPService にバインドする ComboBox があります。イベント リスナーを追加して、ComboBox がデータ プロバイダーから取り込まれた後にコードを実行できるようにしたいと考えています。
これどうやってするの?
標準の HTTPService にバインドする ComboBox があります。イベント リスナーを追加して、ComboBox がデータ プロバイダーから取り込まれた後にコードを実行できるようにしたいと考えています。
これどうやってするの?
Flex には、ASP .Net のような特定のデータ バインディング イベントはありません。ジョンが最初の回答で言ったように dataProvider プロパティを監視する必要がありますが、単にコンボボックスまたはその dataProvider プロパティを監視する必要はありません。次のような設定があるとします。
<!-- Assume you have extracted an XMLList out of the result
and attached it to the collection -->
<mx:HttpService id="svc" result="col.source = event.result.Project"/>
<mx:XMLListCollection id="col"/>
<mx:ComboBox id="cbProject" dataProvider="{col}"/>
次のように changewatcher を設定すると:
// Strategy 1
ChangeWatcher.watch(cbProject, "dataProvider", handler) ;
データが戻ってきても、ハンドラーはトリガーされません。なんで?dataProvider自体は変更されていないため、その基になるコレクションが変更されました。それをトリガーするには、これを行う必要があります。
// Strategy 2
ChangeWatcher.watch(cbProject, ["dataProvider", "source"], handler) ;
コレクションが更新されると、ハンドラーがトリガーされます。戦略 1 を使用して機能させたい場合は、dataProvider を MXML に設定しないでください。代わりに、XMLListCollection のcollectionChangeイベントを処理し、AS で ComboBox の dataProvider を上書きします。
これらはデータバインドされたイベントとまったく同じですか? いいえ、しかし私はそれらを使用しましたが、問題はありませんでした。データが確実にバインドされていることを確認したい場合は、コンボボックスの selectedItem プロパティに changeWatcher を配置して、そこで処理を行ってください。そのイベントが複数回トリガーされ、適切に処理されるように準備してください。
ここで説明されているように、mx.binding.utils.ChangeWatcher を使用できます。
@Herms
リスナーはWebサービス呼び出しの前に確実に追加されます。これは、私のコードがどのように見えるかの例です(私は多くのことを単純化しました...):
私はこのフレックスコンポーネントを持っています:
public class FooComboBox extends ComboBox
{
private var service:HTTPService = null;
public function ProjectAutoComplete()
{
service = new HTTPService();
service.url = Application.application.poxmlUrl;
service.addEventListener(FaultEvent.FAULT,serviceFault);
service.addEventListener(ResultEvent.RESULT,resultReturned);
this.addEventListener(FlexEvent.DATA_CHANGE,dataChange);
}
public function init():void
{
var postdata:Object = {};
postdata["key"] = "ProjectName";
postdata["accountId"] = Application.application.accountId
service.send(postdata);
}
private function resultReturned(event:ResultEvent):void
{
this.dataProvider = service.lastResult.Array.Element;
// thought I could do it here...but no luck...
}
private function dataChange(e:FlexEvent):void
{
// combobox has been databound
mx.controls.Alert.show("databound!");
}
...
}
次に、mxmlファイルにIDが「foo」のFooComboBoxがあり、次のように呼び出します。
foo.init();
コンボボックスが完全にデータバインドされた後、いくつかのコードを実行する必要があります...何かアイデアはありますか?
データプロバイダーが最初に設定されたときにイベントがトリガーされない可能性がありますか?コンストラクターでデータプロバイダーを空の配列に設定してみてください。そうすれば、後でresultReturned()メソッドで最初に割り当てられるのではなく、確実に変更されます。それが役立つかどうかはわかりませんが、一見の価値があります。
また、プロバイダーをlastResult.Array.Elementに設定しています。データプロバイダーはおそらく配列であるはずなので、それは私には少し疑わしいように見えます。確かに、私はあなたのデータがどのように見えるか見当がつかないので、あなたが持っているものは非常に正確である可能性がありますが、それは関連しているかもしれないことに気づきました。たぶんそれはlastResult.Arrayである必要がありますか?
データの読み込みと比較して、どこにリスナーを追加していますか? リスナーを追加する前に、データがロードされ、イベントが発生する可能性はありますか?
コード例validateNow()
で、resultReturned
メソッドで実行してみてください。これにより、コンボ ボックスのプロパティが強制的にコミットされます。問題は、プロパティが設定されていても、実行されるまで新しい値が使用されないことです。実行されるcommitProperties
と、次のフレームで最も早く実行され、validateNow()
すぐに実行されるように強制されます。
コンボ ボックスBindingUtils
のプロパティが変更されたときに通知を受け取るために使用できます。dataProvider
BindingUtils.bindSetter(comboBoxDataProviderChanged, comboBox, "dataProvider");
BindingUtils
mx.binding.utils
パッケージに住んでいます。
BindingUtils
ここでの作業方法について詳しく説明しています:痛みのないプログラムによるデータバインディングは存在しますか?
HTTPService でリッスンすることもできますResultEvent.RESULT
。これは、コンボ ボックスにデータが入力される少し前に呼び出されると思いますが、それで十分かもしれません。