Ответ 1
Не бойтесь MXML. Это отлично подходит для разметки. Если вы пишете свои собственные компоненты многократного использования, тогда их запись в ActionScript может иногда дать вам немного больше контроля, но для многоразовых представлений MXML намного лучше. Это более тонкий, привязки легко настраиваются и т.д.
Однако привязки в чистом ActionScript не должны быть такой болью. Это никогда не будет так просто, как в MXML, где многое сделано для вас, но это может быть сделано не слишком много.
У вас есть BindingUtils
, а методы bindSetter
и bindProperty
. Я почти всегда использую первое, поскольку обычно хочу сделать какую-то работу или называть invalidateProperties
, когда меняются значения, я почти никогда не хочу просто устанавливать свойство.
Что вам нужно знать, так это то, что эти два возвращают объект типа ChangeWatcher
, если вы хотите удалить привязку по какой-то причине, вы должны удержать этот объект. Это то, что делает ручные привязки в ActionScript немного менее удобными, чем в MXML.
Начнем с простого примера:
BindingUtils.bindSetter(nameChanged, selectedEmployee, "name");
Это устанавливает привязку, которая вызывается методом nameChanged
при изменении свойства name
объекта в переменной selectedEmployee
. Метод nameChanged
получит новое значение свойства name
в качестве аргумента, поэтому он должен выглядеть следующим образом:
private function nameChanged( newName : String ) : void
Проблема с этим простым примером заключается в том, что как только вы настроили эту привязку, она будет срабатывать при каждом изменении свойства указанного объекта. Значение переменной selectedEmployee
может измениться, но привязка по-прежнему настроена для объекта, на который указала указанная переменная.
Есть два способа решить эту проблему: либо сохранить ChangeWatcher
, возвращенный BindingUtils.bindSetter
, и вызвать unwatch
на нем, когда вы хотите удалить привязку (а затем вместо этого установите новую привязку) или привязайся к себе. Сначала я покажу вам первый вариант, а затем объясню, что я имею в виду, привязывая себя.
currentEmployee
может быть превращен в пару геттер/сеттер и реализован так (только показ сеттера):
public function set currentEmployee( employee : Employee ) : void {
if ( _currentEmployee != employee ) {
if ( _currentEmployee != null ) {
currentEmployeeNameCW.unwatch();
}
_currentEmployee = employee;
if ( _currentEmployee != null ) {
currentEmployeeNameCW = BindingUtils.bindSetter(currentEmployeeNameChanged, _currentEmployee, "name");
}
}
}
Что происходит, когда установлено свойство currentEmployee
, он смотрит, было ли предыдущее значение, и если это удаляет привязку для этого объекта (currentEmployeeNameCW.unwatch()
), тогда он устанавливает приватную переменную, и если новое значение null
устанавливает новое связывание для свойства name
. Самое главное, что он сохраняет ChangeWatcher
, возвращенный вызовом привязки.
Это основной шаблон привязки, и я думаю, что он работает нормально. Существует, однако, трюк, который можно использовать, чтобы сделать его немного проще. Вместо этого вы можете привязываться к себе. Вместо того, чтобы настраивать и удалять привязки при каждом изменении свойств currentEmployee
, вы можете заставить систему привязки сделать это за вас. В обработчике creationComplete
(или конструкторе или, по крайней мере, некотором раннем времени) вы можете настроить привязку так:
BindingUtils.bindSetter(currentEmployeeNameChanged, this, ["currentEmployee", "name"]);
Это устанавливает привязку не только к свойству currentEmployee
в this
, но также к свойству name
этого объекта. Поэтому в любое время либо вызывается метод currentEmployeeNameChanged
. Нет необходимости сохранять ChangeWatcher
, потому что привязка никогда не будет удалена.
Второе решение работает во многих случаях, но я обнаружил, что первый из них иногда необходим, особенно при работе с привязками в классах без представления (поскольку this
должен быть диспетчером событий и currentEmployee
должен быть привязкой для работы).