четверг, 17 февраля 2011 г.

Биндинг в ActionScript проектах. Часть 1

Биндинг в ActionScript проектах. Часть 1:

Перед разработчиками часто встает вопрос о взамодействии различных классов в приложении. Как классы приложения будут обмениваться информацией между собой, сообщать о тех или иных изменениях? Это должно происходить своевременно. Для этих целей во Flex-фреймворке есть замечательный инструмент, значительно облегчающий жизнь разработчику – биндинг (binding). И как оказалось этой возможностью можно с успехом пользоваться и без использования Flex-фреймворка. Начиная с какой-то-там одной из третьих версий SDK адобовцы постарались максимально изолировать биндинг и все что с ним связано, и теперь его использование добавляет приложению считанные килобайты.

Как бы мы сделали

Немного отвлечемся и поговорим о частном случае. Когда же нам может все это дело пригодиться? Например, при разработке с использованием паттерна MVC встает вопрос о своевременном реагировании компонентов отображения на изменения в модели.

Как известно в MVC классы модели ничего не должны знать и не иметь ссылок ни на классы контроллера, ни на классы отображения. А вот на модель имеют ссылку и контроллер и отображение. Контроллеру нужна ссылка для того чтобы изменить модель, отображению – чтобы отреагировать на изменения. С изменением модели вроде все понятно – нужно поменять свойство. Но как отображение узнает о том что данные были изменены, чтобы самому измениться? Как правило для этих целей используются события. Мы создаем в модели сеттер на нужное нам свойство и в тот момент когда свойство меняется – посылаем соответствующее событие:

1
2
3
4
5
6
7
8
9
private var _text:String;

public function set text (value:String):void{
    if (value == _text){
        return;
    }
    _text = value;
    dispatchEvent(new Event("textChanged"));
}

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

  1. Для каждого свойства в модели придется писать геттер/сеттер. А это много рутинной писанины, класс начинает пухнуть.
  2. При большом количестве свойств в модели будет либо расти количество типов событий, либо придется делать кастомное событие и передавать дополнительно что же именно изменилось и новое значение. В любом случае неудобно.

Как это делается с помощью биндинга

А как же все таки было бы здорово просто написать в классе отображения: “при изменении вот этого свойства вон в том экземпляре класса изменить вот это свойство” или вот так: “при изменении вот этого свойства вон в том экземпляре класса вызвать вот этот метод для обработки”. Так вот стандартный флэксовый биндинг работает именно так.

Давайте посмотрим как это будет выглядеть непосредственно в коде. То свойство за которым нам необходимо пристально следить нужно пометить как bindable. Делается это очень просто, с помощью метатега [Bindable]:

1
2
3
4
5
6
7
8
9
package{
    import flash.events.EventDispatcher;

    // Класс который использует метатег [Bindable] должен обязательно расширяться от EventDispatcher
    public class ClassWithTextProperty extends EventDispatcher{
        [Bindable]
        public var text:String;
    }
}

В классе который должен следить за свойством text в другом классе будет написано следующее [...]

Комментариев нет:

Отправить комментарий