Могу ли я добавить прослушиватель событий в действие привязки данных во Flex? - PullRequest
2 голосов
/ 25 августа 2008

У меня есть ComboBox, который я привязываю к стандартному HTTPService, я хотел бы добавить прослушиватель событий, чтобы я мог запустить некоторый код после заполнения ComboBox из поставщика данных.

Как я могу это сделать?

Ответы [ 8 ]

2 голосов
/ 30 июля 2010

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}"/>

Теперь, если вы установите переключатель, как это:

// Strategy 1
ChangeWatcher.watch(cbProject, "dataProvider", handler) ;

Ваш обработчик будет не срабатывать при возврате данных. Зачем? Поскольку сам dataProvider не изменился - его базовая коллекция изменилась. Чтобы вызвать это, вы должны сделать это:

// Strategy 2
ChangeWatcher.watch(cbProject, ["dataProvider", "source"], handler) ;

Теперь, когда ваша коллекция обновится, ваш обработчик сработает. Если вы хотите, чтобы это работало с использованием Стратегии 1, не устанавливайте ваш dataProvider в MXML. Скорее обработайте событие collectionChange вашего XMLListCollection и в AS перезаписайте dataProvider ComboBox.

Это точно так же, как событие с привязкой к данным? Нет, но я использовал их и никогда не было проблемы. Если вы хотите, чтобы абсолютно были уверены, что ваши данные имеют привязку , просто поместите changeWatcher в свойство selectedItem вашего комбинированного списка и выполните там обработку. Просто будьте готовы к тому, что это событие сработает несколько раз, и обработайте его соответствующим образом.

1 голос
/ 25 августа 2008

Вы можете использовать mx.binding.utils.ChangeWatcher, как описано здесь .

0 голосов
/ 26 августа 2008

В вашем примере кода попробуйте запустить validateNow() в методе resultReturned. Это заставит поле со списком зафиксировать его свойства. Дело в том, что, хотя свойство установлено, новое значение не используется до тех пор, пока не будет запущено commitProperties, что будет выполнено в ближайшее время в следующем кадре, validateNow() заставит его выполнить это сразу.

0 голосов
/ 25 августа 2008

Может быть, событие не запускается, когда поставщик данных впервые установлен? Попробуйте установить поставщик данных для пустого массива в конструкторе, чтобы он определенно изменил , а не просто был первоначально назначен позже в вашем методе resultReturned (). Понятия не имею, поможет ли это, но оно того стоит.

Кроме того, вы устанавливаете провайдер для lastResult.Array.Element. Это выглядит немного подозрительно для меня, поскольку поставщик данных, вероятно, должен быть массивом. Конечно, я понятия не имею, как выглядят ваши данные, поэтому то, что вы имеете, вполне может быть правильным, но я заметил, что это может быть связано. Может быть, это просто lastResult.Array?

0 голосов
/ 25 августа 2008

@ Herms

Слушатель определенно добавляется перед вызовом веб-службы, вот пример того, как выглядит мой код (я упростил многие вещи ...):

У меня есть этот гибкий компонент:


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 у меня есть FooComboBox с идентификатором "foo", и я вызываю:


foo.init();

Мне нужно выполнить некоторый код после того, как выпадающий список полностью привязан к базе данных ... есть идеи?

0 голосов
/ 25 августа 2008

Куда вы добавляете слушателя по сравнению с загрузкой данных? Возможно ли, что данные загружаются и событие запускается до того, как вы добавили слушателя?

0 голосов
/ 25 августа 2008

Вы также можете прослушивать ResultEvent.RESULT на HTTPService, который будет вызываться немного, прежде чем заполнить поле со списком, я думаю, но это может быть достаточно.

0 голосов
/ 25 августа 2008

Вы можете использовать BindingUtils, чтобы получать уведомления при изменении свойства dataProvider поля со списком:

BindingUtils.bindSetter(comboBoxDataProviderChanged, comboBox, "dataProvider");

BindingUtils живет в пакете mx.binding.utils.

У меня есть более подробное описание работы с BindingUtils здесь: Существует ли безболезненная программная привязка данных?

...