是否可以在Flex中的数据绑定操作中添加事件侦听器?
我有一个绑定到标准HTTPService的ComboBox,我想添加一个事件侦听器,以便在从数据提供者填充ComboBox之后可以运行一些代码。
我怎样才能做到这一点?
解决方案
回答
当组合框的dataProvider属性更改时,我们可以使用BindingUtils来获得通知:
BindingUtils.bindSetter(comboBoxDataProviderChanged, comboBox, "dataProvider");
BindingUtils存在于mx.binding.utils包中。
我在这里对如何使用" BindingUtils"进行了较长的描述:是否存在无痛的编程数据绑定?
回答
我们还可以在HTTPService上监听ResultEvent.RESULT
,我想在组合框被填充之前会稍稍调用它,但这可能就足够了。
回答
我们可以按照此处所述使用mx.binding.utils.ChangeWatcher。
回答
与数据加载相比,我们在哪里添加侦听器?在添加侦听器之前,是否有可能正在加载数据并触发了事件?
回答
@赫姆斯
监听器肯定是在Web服务调用之前添加的,这是我的代码示例的示例(我简化了很多事情...):
我有这个flex组件:
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?
回答
在示例代码中,尝试在resultReturned
方法中运行validateNow()
。这将迫使组合框提交其属性。问题是,即使设置了属性,也要等到运行commitProperties
后才使用新值,该值最早将在下一帧执行,而validateNow()
则必须立即执行。
回答
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使其工作,请不要在MXML中设置dataProvider。而是处理XMLListCollection的collectionChange事件,并在AS中覆盖ComboBox的dataProvider。
这些与数据绑定事件完全相同吗?不,但是我用过它们,从来没有遇到过问题。如果要绝对确定数据已绑定,只需将一个changeWatcher放在组合框的selectedItem属性上,然后在那里进行处理。只是准备让该事件触发多次并适当地处理它即可。