是否可以在Flex中的数据绑定操作中添加事件侦听器?

时间:2020-03-05 18:42:55  来源:igfitidea点击:

我有一个绑定到标准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属性上,然后在那里进行处理。只是准备让该事件触发多次并适当地处理它即可。