Не бойся 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
должен быть привязан, чтобы он работал).