我有一个绑定到标准 HTTPService 的 ComboBox,我想添加一个事件侦听器,以便在从数据提供程序填充 ComboBox 后运行一些代码。
我怎样才能做到这一点?
我有一个绑定到标准 HTTPService 的 ComboBox,我想添加一个事件侦听器,以便在从数据提供程序填充 ComboBox 后运行一些代码。
我怎样才能做到这一点?
Flex 没有像 ASP .Net 那样的特定数据绑定事件。您必须像 John 在第一个答案中所说的那样注意 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。
这些与数据绑定事件完全相同吗?不,但我用过它们,从来没有遇到过问题。如果您想绝对确定您的数据已绑定,只需在组合框的 selectedItem 属性上放置一个 changeWatcher 并在那里进行处理。只需准备好多次触发该事件并适当处理即可。
您可以使用此处描述的 mx.binding.utils.ChangeWatcher 。
在您的示例代码中,尝试validateNow()
在resultReturned
方法中运行。这将强制组合框提交其属性。问题是,即使设置了属性,新值也不会在commitProperties
运行之前使用,它最早会在下一帧执行,validateNow()
强制它立即完成。
首次设置数据提供者时,可能不会触发事件?尝试在构造函数中将数据提供者设置为一个空数组,这样它肯定会发生变化,而不是稍后在你的 resultReturned() 方法中最初分配。我不知道这是否会有所帮助,但值得一试。
此外,您将提供程序设置为 lastResult.Array.Element。这对我来说有点可疑,因为数据提供者可能应该是一个数组。当然,我不知道您的数据是什么样的,所以您所拥有的很可能是正确的,但我注意到这可能是相关的。也许它应该只是 lastResult.Array?
与加载数据相比,您在哪里添加侦听器?在添加侦听器之前,是否有可能正在加载数据并触发事件?
@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();
在组合框完全数据绑定后,我需要执行一些代码......有什么想法吗?
当组合框的属性发生变化时,您可以使用它BindingUtils
来获得通知:dataProvider
BindingUtils.bindSetter(comboBoxDataProviderChanged, comboBox, "dataProvider");
BindingUtils
住在mx.binding.utils
包里。
我对如何使用BindingUtils
这里有更长的描述:是否存在无痛的编程数据绑定?
您还可以ResultEvent.RESULT
在 HTTPService 上侦听,我猜在组合框填充之前会稍微调用它,但它可能已经足够好了。