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





Вы можете использовать BindingUtils, чтобы получать уведомления при изменении свойства dataProvider поля со списком:
BindingUtils.bindSetter(comboBoxDataProviderChanged, comboBox, "dataProvider");
BindingUtils находится в пакете mx.binding.utils.
У меня есть более подробное описание работы с BindingUtils здесь: Существует ли безболезненная программная привязка данных?
Вы также можете прослушать ResultEvent.RESULT в HTTPService, который, я думаю, будет вызываться немного до того, как будет заполнено поле со списком, но этого может быть достаточно.
Вы можете использовать mx.binding.utils.ChangeWatcher, как описано здесь.
Где вы добавляете слушателя по сравнению с загрузкой данных? Возможно ли, что данные загружаются и событие запускается до того, как вы добавили слушателя?
@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();
Мне нужно выполнить код после того, как поле со списком будет привязано к базе данных полностью ... есть идеи?
Может быть, событие не срабатывает при первой установке поставщика данных? Попробуйте установить для поставщика данных пустой массив в конструкторе, чтобы он определенно изменение, а не просто изначально назначался позже в вашем методе resultReturned (). Понятия не имею, поможет ли это, но попробовать стоит.
Кроме того, вы устанавливаете в качестве поставщика lastResult.Array.Element. Мне это кажется немного подозрительным, поскольку поставщиком данных, вероятно, должен быть массив. Конечно, я понятия не имею, как выглядят ваши данные, поэтому то, что у вас есть, вполне может быть правильным, но я заметил, что это может быть связано. Может, стоит просто lastResult.Array?
В вашем примере кода попробуйте запустить validateNow() в методе resultReturned. Это заставит поле со списком зафиксировать свои свойства. Дело в том, что даже если свойство установлено, новое значение не используется до тех пор, пока 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}"/>
Теперь, если вы установите Changeewatcher следующим образом:
// 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 вашего поля со списком и выполните там свою обработку. Просто будьте готовы к тому, что это событие сработает несколько раз и обработает это соответствующим образом.