SlideShare una empresa de Scribd logo
1 de 50
Flex Pure MVC архитектура для
 приложений enterprise уровня
  Sergiy Shychynov (EPAM)   2012-03-24
Содержание
1.        Сначала мы вспомним основные составляющие
          микроахитектуры PureMVC.
2.        Далее рассмотрим структуру и задачи, возникающие при
          использовании PureMVC в больших проектах.
     1.        Разновидности и жизненный цикл элементов системы
     2.        Необходимость синхронизации работы медиаторов с асинхронно
               создаваемыми видимыми элементами.
3.        «Страничная» архитектура для PureMVC проекта:
     1.        Управление View компонентами в «страничной» архитектуре:
          1.     Отложенное (deferred) создание,
          2.     Расположение в иерархии Display Objects.
     2.        Жизненный цикл «страницы», дескриптор «страницы»
     3.        Прелоадер страницы
4.        Использование модулей в «страничной» архитектуре.
Основные составляющие PureMVC
используя презентацию Samuel Asher Rivello)
http://www.adobe.com/newsletters/inspire/december20
08/articles/article6/index.html

MVC in PureMVC
Схема взаимодействия компонентов PureMVC
для выполнения элементарной операции
   Внешний вид компонента Hello Google –
    кнопка и текстовое поле для сообщения
   Последовательность элементарных
    действий выполняемых при нажатии
    кнопки
   Положение этих действий на диаграмме
    PureMVC
Основные задачи, возникающие при
использовании PureMVC в больших проектах.
«Приложение enterprise уровня» - БОЛЬШИЕ

БОЛЬШОЕ количество РАЗНЫХ форм и компонентов,
которые необходимо будет использовать в разных
ситуациях и в разное время

Речи о том, что все элементы будут созданы
одновременно или заранее быть не может. Более того –
было бы неплохо, чтобы и грузить их все сразу не
требовалось.

Рассмотрим несколько разных «видов» гипотетического
большого приложения.
Форма - Списки контактов и контактных групп
Форма – менеджер валют
Форма – редактирование контакта
Форма - Аудит
Форма – Редактирование конвейера операций
маппинг процессора для бла-бла-бла
Форма – Маппинг полей метода сервиса
передачи телефонных сообщений.
3 вида компонентов
Среди всего UI большого приложения можно
выделить элементы (подсистемы)
1.   постоянно находятся на экране и доступны для взаимодействия.
2.   могут вызываться пользователем на экран по желанию и ведут себя
     относительно независимо от других элементов UI.
3.   которые имеют отношение к текущей операции, выполняемой
     пользователем, показываются на экране когда он начинает
     выполнять эту операцию и будут убраны с экрана когда он эту
     операцию завершит. Причем таких циклов появления и
     исчезновения с экрана может быть много. Этот третий тип подсистем
     мы будем в дальнейшем называть страницами – Pages.



И если операции по обслуживанию жизненного цикла для 1 и 2 типа можно
выполнить один раз (например в StartupCommand), то выполнение всех
нижеперечисленных действий для компонентов подсистем 3-его типа
является рутинной операцией и нуждается в автоматизации.
Жизненный цикл элементов системы и
основные операции над ними.
1.        создать и разместить в иерархии DisplayObjects необходимые компоненты - ViewComponents.
2.        создать и зарегистрировать необходимые медиаторы – Mediators.
3.        связать медиаторы с соответствующими компонентами
                ссылки на компоненты, прослушивание события от компонентов
4.        зарегистрировать необходимые для работы подсистемы команды – Commands
5.        создать и зарегистрировать необходимые для работы прокси – Proxy,
6.        отобразить в компонентах валидные данные
     1.         загружаются с сервера - определенное время
     2.         загружаются с сервера – «ошибки технические»
     3.         политики безопасности – запрещено смотреть данные – «ошибки логические»
     4.         Не стоит показывать на экране новые компоненты, еще не заполненные данными, до того как эти данные будут
                получены с сервера.
     5.         Это процесс мы будем называть предзагрузка – preloader.
7.        основной цикл работы – стандартный
     1.         Отдельный вопрос – это обработка ошибок (серверных). Бывают устранимые и неустранимые ошибки – остаемся на
                странице, обновляем или покидаем ее.
8.        после завершения операции - корректно освободить ресурсы системы от текущей «страницы»
     1.         Отписывание медиаторов от событий, которые они прослушивали от компонентов.
     2.         Удаление «актеров» PureMVC (медиаторов)
           1.       «отписать» медиаторы от системы (unregister)
           2.       удалять медиаторы или сохранять их в «кэше»
           3.       команды тоже можно «отписать» от системы,
           4.       прокси отписывать от системы и удалять – как правило не нужно и даже вредно.
     3.         Удаление видимых компонентов - операция создания компонента и добавления его в DisplayList более ресурсоемкая,
                чем сделать невидимый компонент – видимым. НЕ удалять а делать невидимыми
     4.         Очистить ссылки на временные данные - Garbage Collector освободит память.
Необходимость синхронизации работы медиаторов с
асинхронно создаваемыми видимыми элементами.
   Как известно видимые элементы – компоненты флекса не
    создаются мгновенно по запросу. Как правил от момента
    создание экземпляра компонента, установки его свойств и
    добавления его в иерархию DisplayObjects проходит некоторое
    время и несколько этапов, прежде чем событие
    «creationComplete» дает нам знать, что компонент и все его
    подкомпоненты полностью созданы и готовы к работе.
   До этого момента медиатор, даже если и будет иметь ссылку на
    компонент, не сможет полноценно с ним работать.

   DefferedMediator - решает проблему асинхронного создания
    компонентов. Откладывает вызовы initialize и activate до
    момента, когда компонент будет создан и инициализирован. А
    потом еще откладывает update до момента, когда все
    медиаторы из списка будут активированы.
DefferedMediator
   constructor() – чистый конструктор

   create(); - все что хотелось сделать в конструкторе

   initialize(); - в том числе addViewListeners уровня инициализации

   activate();   - в том числе addViewListeners уровня активации


waitForMediatorsActivation(mediatorNames);

   update(); - основной цикл

   deactivate(); – в том числе автоматически удаляет eventListeners уровня активации

   finalize(); – в том числе автоматически удаляет eventListeners уровня
    инициализации
Кто, когда и как создает видимые элементы.
Медиатор знает класс своего(-их) компонентов.
Медиатор знает где должен быть его компонент.

     SlotViewComponentDescription
       viewComponentName = "M1“
       viewComponentSlot =
     "SlotAMediator"
       viewComponent = UIComponent

                                     Медиатор-слотхолдер
     Медиатор-клиент                 “SlotAMediator” получает
     M1Mediator создает              нотификейшен, адресованный
     компонент и отправляет его      ему и добавляет в свой слот
                                     новый компонент под именем
     слоту "SlotAMediator" -
                                     "M1“.
     просит его хранить под
     именем "M1“.
     Обычно в методе create()        Слот – это обычно ViewStack
                                     или другой контейнер.
Пример взаимодействия слот-холдера и его
клиентов
«Страничная» PureMVC архитектура
«Страница» – это некоторое множество компонентов,
функционирующих совместно в одном промежутке
времени.

Эти компоненты и обслуживающие их актеры PureMVC
совместно создаются, работают и удаляются.

Чтобы не писать отдельные команды для открытия
каждой страницы, была создана единая команда
открытия новой страницы ViewPageCommand, которая
использует PageDescription страницы и работает
совместно с Pages Proxy.
Основные задачи                                PagesProxy
     хранение справочника всех страниц системы
    function getPageDescription(pageName:String):PageDescription



     хранение информации о текущей открытой странице
    (ее имя, дескриптор, стейт, состояние редактирование, helpContext и прочее)




Соответственно все страницы имеют уникальные имена
public class Pages
{
     public static const ABOUT:String = "about";
     public static const ADMIN_EMAIL_TEMPLATE_EDIT:String = "adminEmailTemplateEdit";
     public static const DOCUMENT_TRANSLATION:String = "documentTranslation";
…
}

и дескрипторы
PageDescription
   pageName:String,


   preloader:Class,        - клоасс-наследник BasePagePreloader


   mediators:Array,        - список классов-наследников BaseMediator
   proxies:Array = null,   - список классов-наследников BaseProxy
   commands:Array = null, - список CommandDescription(name:String,   commandClass:Class)



   stateParams:Object = null,       - редко встречающиеся доп. параметры


   pageTitle:String = null,     }   - часто встречающиеся доп. параметры
   breadcrumbs:Array = null. … }
Вызов ViewPageCommand
Регистрация команды
facade.registerCommand(BaseNotifications.VIEW_PAGE, ViewPageCommand);




Вызов команды активации страницы
var params:PageNotificationParams = new PageNotificationParams();
params.pageName = Pages.IMPORT_REPORT;
params.id = importReport.id;
params.documentType = importReport.dataType;
sendNotification(BaseNotifications.VIEW_PAGE, params);




PageNotificationParams
   var pageName:String;
   var pageState:String;
   var id:Number;
   var backPageName:String;
   var preloader:BasePreloaderMediator; - создается и добавляется в процессе открытия
Пример дескриптора страницы
new PageDescription( Pages.QUESTIONNAIRE,
    QuestionnaireAnswerPreloader,
    [QuestionnaireSlotHolderMediator, QuestionnaireAnswerMediator],
    [QuestionnairesProxy, ProcessEditProxy, ProcessTypesListProxy, TimeScaleProxy],
    [
         new CommandDescription(SPNotification.FIND_NEW_QUEST, LoadQuestiannairCommand),
         new CommandDescription(SPNotification.UPDATE_ASSET_QUEST, UpdateAssetCommand),
    ],
    { questionnaireComponentState: QuestionnaireComponentState.ANSWER },
    "Questionnaire Registry"
)




Далее описание алгоритма работы ViewPageCommand …
pageDescriptor – ищем по имени страницы
            Проверяет наличие дескриптора страницы                stateParams : {} – доп. набором параметров
                                                                  страницы не вошедшие в дескриптор (редко)
                     (если надо грузит нужный модуль)
                                                                  viewParams : PageNotificationParams –
                                                                  параметры страницы, заполняемые при ее
                                                                  открытии (все которые нужны часто)

          Создает и регистрирует необходимые прокси


                                                                           validate() &
         Создает и запускает прелоадер                  load()             препроцессинг          -
- отписывает от системы медиаторы
 - подчищает «временные» данные                                                +
 - отписывает медиатор от events
                                       Закрывает текущую страницу
компонентов                                                                                 Страница не
 - добавляет прелоадер во viewParams                                                        открывается

                           Регистрирует команды
                                                                 Если создаются, то в следующем порядке:
                                                                  - Конструктор
            Создает (или достает из кеша) медиаторы               - Setup params (stateParams и viewParams)
                                                                  - create()

                                                                 Медиаторы должны создать свои компоненты,
                          Активирует медиаторы.                  разместить их в иерархии DisplayLists, сделать
                                                                 видимыми и подписаться на необходимые events.


      После активации всех вызывается update()
Прелоадер – Preloader
Прелоадер загружает несколько «частей» данных (прокси или
делегаты).
После полной загрузки всех частей возможна их валидация и
дополнительная обработка.
Если валидатор выдает false, страница не будет открыта - вместо этого
будет выведено сообщение об ошибке.


Фрагмент кода вызова прелоадера при открытии страницы
if(pageDesc.preloader != null)
{
    setLoadingState(true);
    registerProxies(); // for preloading
    var preloaderMediator:BasePreloaderMediator = new (pageDesc.preloader)();
    preloaderMediator.viewParams = params;
    preloaderMediator.stateParams = pageDescriptor.stateParam;
    preloaderMediator.callback = executeAfterPreload;
    preloaderMediator.load();
BasePreloaderMediator
   var stateParams:Object;
   var viewParams:PageNotificationParams;


Override it to create more preloader parts. You can use viewParams and stateParams.
   function load():void {
       addDelegatePreloaderPart("YYYid", ResourceTypeDelegate.instance.getResourceTypeById(id));
       //...
       addNotificationPreloaderPart("XXXid", XXXResultNotification, XXXFaultNotification);
       xxxProxy.load(blablabla);
       //...
       activate();
   }
Override it to validate loaded data. If ERROR - set preloader.errorKey before returning false value.
   function validate():Boolean {
       if(preloader.errorKey == null)   {
           // достаем нужное нам данное и проверяем
           getPart("YYYid") – используем для проверки
       }
       return (preloader.errorKey == null);
   }
Пример прелоадера «детям до 16»
   public class ManageGroupMembershipPreloader extends BasePreloaderMediator
   {
       override public function load():void {
           if(!isNaN(id))
                addDelegatePreloaderPart(ContactProxy.CONTACT, ContactDelegate.instance.getContactById(id) );


           addNotificationPreloaderPart(LanguageProxy.PLAIN_LANGUAGE_LIST,
                    SPNotification.PLAIN_LANGUAGE_LIST_LOADED, SPNotification.PLAIN_LANGUAGE_LIST_FAILED);
           LanguageProxy(facade.retrieveProxy(LanguageProxy.NAME)).getPlainLanguageList();


           super.load();
       }


       override public function validate():Boolean {
           if(super.validate()) {
               var contact:Contact = getPart(ContactProxy.CONTACT) as Contact;
               if(contact != null && contact.age < 16)
                 setPreloaderError("Просмотр этой страницы не разрешен детям до 16");
               return super.validate();
           }
   }
Модульность
В настоящее время система имеет:
   полторы сотни (150) основных страниц со связанными с ними rollover
    формами,
   несколько десятков popup-форм
   некоторое кол-во подсистем,
            работающих постоянно на экране,
            вызываемых по требованию пользователя
            или работающий в качестве «демонов» – daemon (ping, system messages)
            и «сервисов» (messages, multiple operations, progress indication etc.)



Кодовая база клиентской части проекта включает более 2000 файлов. Из них
более 1600 as файлов и около 400 mxml.


При этом с точки зрения заказчика это все разбито на 8 логических «модулей»
и лицензия на использование каждого из них может покупаться отдельно.


Кроме того многие пользователи могут не иметь доступа к некоторым модулям
(администрирование, отчеты) по соображениям безопасности или в соответствии
с их ролями в системе.
Соображения по поводу Модульности
 Необходимо: при начальной загрузке загружать только ядро системы, а все
 дополнительные, не всегда или редко используемые возможности подгружать по
 требованию. Для уменьшения времени загрузки и потребляемого трафика.

    RSL для этого использовать нельзя:
        приходилось бы вручную выбирать какие классы включать в эту библиотеку а какие - нет


    Флексовые модули для этого как бы не задумывались, но воспользоваться ими получилось:
        линкер mxmlc при компиляции модуля позволяет собрать все классы, по цепочке зависимостей,
        есть возможность указать линкеру, что необходимо исключить классы, которые уже есть в ядре
         приложения.


    «Страничная» организация – основа сборки модуля.
        PageDescriptor – это узел для дерева линковки всех классов
        модуль подгружает ViewPageCommand в момент когда впервые понадобиться страница
         содержащаяся в этом модуле
        узнает из справочника в каком модуле находится нужная страница (moduleDescriptors.xml )
        после загрузки модуля, все PageDescriptors из модуля добавляются в PagesProxy
Структура иерархии модулей
   Module – единица компиляции и линковки
   ModuleDescription – содержит полный набор всех Page
    Descriptors модуля
   PageDescriptionsXXX – логически сгруппированные наборы
    дескрипторов страниц

moduleDescriptors.xml – справочник, содержащий
информацию о том какая страница в каком модуле содержится

flex-include-vo.xml – список всех VO системы для включения в
ядро системы (решение проблемы регистрации VO для
ремотинга)

Соответствующие ANT скрипты.
!!! НИКОГДА не включайте модули из среды Flash Builder!!!
public function ModuleMain()
{
    super();

    _moduleDescription = new ModuleDescriptionMain();

    //NameUtils.registerServerClass(ContactTask);

    initializeModule();
}



public function ModuleDescriptionMain()
{
    super("ModuleMain", [], []
        .concat(PageDescriptionsMain.pageDescriptions)
        .concat(PageDescriptionsContacts.pageDescriptions)
        .concat(PageDescriptionsReporting.pageDescriptions)
        );
}
public class PageDescriptionsResourcesAssets
{
public static const commonBreadcrumbs:Array = [Pages.R_A_VIEW_ROOT_RESOURCES];
public static const commonProxies:Array = [ResourceTypeProxy, ParentListProxy, SessionDataProxy,AssetProxy, ProcessEditProxy, ProcessesListProxy ];
public static const pageDescriptions:Array = [/////////////////////////////////////////////


new PageDescription(Pages.UPDATE_RESOURCE_TYPE,
    PageState.ADD_EDIT_VIEW,
    ResourceTypeEditPreloader,
    Pages.R_A_VIEW_ROOT_RESOURCES,
    [ResourcesSlotHolderMediator, ResourceTypeEditMediator],
    [SessionDataProxy, AssetProxy, ProcessEditProxy],
    [
       new CommandDescription(SPNotification.FIND_ASSET_FOR_DETAILS, LoadAssetCommand),
       new CommandDescription(SPNotification.FIND_ASSET_FOR_EDIT, LoadAssetEditCommand),
    ],
    {accessArea: AccessArea.RESOURCE_TYPES},
    commonBreadcrumbs.concat(),
    "page.updateResourceType.title",
    "page.updateResourceType.breadcrumbLabel",
    null
).addAddPageState(null,
    "page.createResourceType.title",
    "page.createResourceType.breadcrumbLabel"
).addViewPageState(null,
    "page.updateResourceType.viewTitle",
    "page.updateResourceType.viewBreadcrumbLabel"
).addLibraryPageState(
    Pages.R_A_UPDATE_RESOURCE_TYPE_FOR_LIBRARY
),


new PageDescription(Pages.QUESTIONNAIRE, PageState.EDIT_VIEW,
    QuestionnaireAnswerPreloader, null,
    [QuestionnaireAnswerMediator],
    [QuestionnairesProxy, ProcessEditProxy, ProcessTypesListProxy],
    null,
    {questionnaireComponentState:QuestionnaireComponentState.ANSWER},
    [TreeNodeBase.NODE_BIA]
).registerRollover(Rollovers.QUESTIANNAIRE_RECOVERY_SCHEDULE, PageState.ADD_EDIT_VIEW
).registerRollover(Rollovers.QUESTIONNAIRE_ADD_PROCESS, PageState.ADD_EDIT_VIEW
)

] /////////////////////////////////////////////
}
moduleDescriptors.xml
   <?xml version="1.0" encoding="UTF-8"?>
   <Modules>
     <Module name="ModuleMain">
       <Pages>
         <Page name="about"/>
         <Page name="myTasksPage"/>
       </Pages>
       <Dependencies/>
     </Module>
     <Module name="ModuleAdministration">
       <Pages>
         <Page name="adminLogo"/>
         <Page name="adminLanguageEditor"/>
         <Page name="auditTrail"/>
       </Pages>
       <Dependencies/>
     </Module>
   </Modules>
Проблема регистрации классов для
римотинга.
[RemoteClass(alias="com.os.sp.domain.messaging.MessagesGroup")]
public class MessagesGroup extends MessagesGroupBase implements IOSSPMessage {}



!!! Не   регистрирует класс, если VO линкуется через модуль!


Решение проблемы:
1) в модуле делаем
   registerClassAlias(getClassServerName(classRef), classRef);
2) линкуем все VO в ядро системы (flex-include-vo.xml)

   <?xml version="1.0"?>
   <flex-config>
   <includes append="true">
   <symbol>com.os.sp.domain.messaging.MessagesGroup</symbol>
        <symbol>com.os.sp.domain.messaging.SmsCostConfig</symbol>
        <symbol>com.os.sp.domain.integrity.InvalidRecord</symbol>
   </includes>
   </flex-config>
Фрагмент ant-task-а компиляции основного
приложения (ядра системы)
   <property name="FLEX_INCLUDE_VO_CONFIGURATION" value="${MAIN_SOURCE_FOLDER}/flex-include-vo.xml" />


   <mxmlc file="${MAIN_SOURCE_FOLDER}/${ROOT_APPLICATION}.mxml"
       output="@{output}.swf"
       link-report="${BUILD_FOLDER}/${ROOT_APPLICATION}.${FULL_LINK_REPORT_POSTFIX}"
       >
       <load-config filename="${FLEX_LOCAL_CONFIGURATION}"/>
   </mxmlc>


   Компиляция модулей
   <target name="compile-modules" if="flex.modular.exist">
       <compile-module-simple moduleName="ModuleAdministration" />
       <compile-module-simple moduleName="ModuleMessaging" />
       <compile-module-simple moduleName="ModuleImportExport" />
   </target>


   Фрагмент из макроопределения компиляции модуля
   <mxmlc file="${MODULE_SOURCE_FOLDER}/@{moduleName}.@{moduleType}"
           output="${BUILD_FOLDER}/@{moduleName}.swf"
           load-externs="${BUILD_FOLDER}/@{dependsOn}.${FULL_LINK_REPORT_POSTFIX}"
           >
   </mxmlc>
КОНЕЦ

Sergiy_Shychynov@epam.com
НО
ОСТАЛОСЬ НЕ ОХВАЧЕННЫМ

Взаимодействие View Components и Mediators
    Шаблон «страницы»
    Интерфейс «страничного» View Component
    Обмен данными между медиатором и View
     компонентом.
    Состояние «редактирования» (Editing state)
    Обработка нажатий кнопок (Buttons)
    Обработка других команд (пример – Chevrons)
 …
А ТАКЖЕ

    Базовые классы медиаторов
        Медиатор формы
        Медиатор листа
        Медиатор попапа
    Подсистема Proxy-Delegate-Preloader
    Локализация приложений

 …
Приложение: особенности реализации
SlotHolder медиаторов
   Задача по созданию и связыванию вью компонентов с
    медиаторами возложена на медиатор.
   Медиатору известен класс его компонента. При
    создании медиатора – в методе create() – медиатор
    создает инстанс класса вью компонента и отправляет
    его слот-холдер медиатору чтобы тот поместил его
    себе в DisplayList.
Способы создания и связывани компонента с
медиатором.
   protected function setupMediator(…)
       mediatorName:String = null,

       // AUTO – такое же как имя класса – для регистрации в PureMVC



       viewComponentReference:Object = null,

       // 1) null must be null,

       // 2) component class

       // 3) component instance (descendant of UIComponent)



       viewComponentName:String = null, // viewComponent custom name
       // AUTO – по имени медиатора без постфикса Mediator

       // будет использовано как id и name в слотхолдере



       viewComponentSlot:String = null, // specific slot for register/find viewComponent (if need)


       viewComponentInitAction:int = 0 // special init action (0 - no action)
              INIT_NONE:int = 0; // no action



              INIT_FIND_OR_WAITING_FOR_THE_VIEW_COMPONENT:int = 1;

              // find view component with appropriate name in appropriate slot or (in not found)

              // listen for the BaseNotifications.SLOT_VIEW_COMPONENT_CREATION_COMPLETE notification



              INIT_FIND_VIEW_COMPONENT:int = 2;

              // find view component with appropriate name in appropriate slot


              INIT_ADD_TO_SLOT:int = 4;

              // add view component to appropriate slot using appropriate name
Особенности реализации протокола взаимодействия
слот-холдер медиаторов с их клиентами.
   override public function listNotificationInterests():Array
   {
       return (slots == null)
           ? super.listNotificationInterests()
           : super.listNotificationInterests().concat(
                  BaseNotifications.SLOT_VIEW_COMPONENT_ADD,
                  BaseNotifications.SLOT_VIEW_COMPONENT_REMOVE_BY_NAME,
                  BaseNotifications.SLOT_VIEW_COMPONENT_SHOW,
                  BaseNotifications.SLOT_VIEW_COMPONENT_HIDE,
                  BaseNotifications.SLOT_VIEW_COMPONENT_FIND
             );
   }

   override public function handleNotification(notification:INotification):void
   {
       super.handleNotification(notification);
       …
   }
   private function defaultSlotHolderNotificationHandler(notification:INotification):void
   {
       if(slots && slots[notification.getType()]) {
         var desc:SlotViewComponentDescription = notification.getBody() as SVCD;
         var component:UIComponent;
         component = getViewComponentFromSlot(desc.viewComponentSlot, desc.viewComponentName);
         switch(notification.getName()) {
             case BaseNotifications.SLOT_VIEW_COMPONENT_SHOW:
               FlexUIComponentsUtils.showViewComponent(component, true);
               break;
             case BaseNotifications.SLOT_VIEW_COMPONENT_HIDE:
               component.visible = false;
               break;
             case BaseNotifications.SLOT_VIEW_COMPONENT_ADD:
               addViewComponentToInternalSlot(desc);
               desc.viewComponent = null; // mark viewComponent as added
               break;
             case BaseNotifications.SLOT_VIEW_COMPONENT_REMOVE_BY_NAME:
               removeViewComponentFromSlotByName(desc);
               break;
             case BaseNotifications.SLOT_VIEW_COMPONENT_FIND:
               desc.viewComponent = component;
               break;
   }}}
Интересный Антипаттерн
Далее описан антипаттерн, который используется для оптимизации взаимодействия слотхолдеров. Но
мне не стыдно, потому что это, с одной стороны – служит оптимизации (можно было и не делать), с
другой – можно было бы без этого обойтись просто воспользовавшись синглтоном-менеджером.


   * Register handler for Notification - works just like addEventListebner.
   * It doesn't depend on registerMediator/removeMediator !BE AWARE!
   function addNotificationListener(notificationName:String, handler:Function):void
   {
       org.puremvc.as3.core.View.getInstance().registerObserver(notificationName,
                                                          new Observer(handler, this) );
   }


   * Remove Notification handler - works just like removeEventListebner.
   * It doesn't depend on registerMediator/removeMediator !BE AWARE!
   function removeNotificationListener(notificationName:String):void
   {
       org.puremvc.as3.core.View.getInstance().removeObserver(notificationName, this );
   }
Пример использования:
   * Try to add view component in appropriate external slot. If there isn't
   * appropriate slot then start waiting for SLOT_CREATION_COMPLETE.
   function addViewComponentToExternalSlot():void {
       var desc:SlotViewComponentDescription = new SlotViewComponentDescription
            viewComponentName, viewComponentSlot, viewComponent as UIComponent );


        var addNotification:INotification = new Notification(
              BaseNotifications.SLOT_VIEW_COMPONENT_ADD, desc, viewComponentSlot);


        facade.notifyObservers(addNotification);


        if(desc.viewComponent != null) // его бы обнулили если бы он был найден
        {
              addNotificationListener(BaseNotifications.SLOT_CREATION_COMPLETE,
                 handleSlotCreationCompleteNotificationToAddViewComponent);
        }
   }

Más contenido relacionado

La actualidad más candente

FFCMS - вводная для пользователя
FFCMS - вводная для пользователяFFCMS - вводная для пользователя
FFCMS - вводная для пользователяzenn1989
 
Moxy – реализация MVP под Android. С щепоткой магии
Moxy – реализация MVP под Android. С щепоткой магииMoxy – реализация MVP под Android. С щепоткой магии
Moxy – реализация MVP под Android. С щепоткой магииYuri Shmakov
 
Объять необъятное, или как использовать несколько MVVM фреймворков в одном XA...
Объять необъятное, или как использовать несколько MVVM фреймворков в одном XA...Объять необъятное, или как использовать несколько MVVM фреймворков в одном XA...
Объять необъятное, или как использовать несколько MVVM фреймворков в одном XA...Denis Tsvettsih
 
Создание графического интерфейса пользователя мобильных Android приложений (ч...
Создание графического интерфейса пользователя мобильных Android приложений (ч...Создание графического интерфейса пользователя мобильных Android приложений (ч...
Создание графического интерфейса пользователя мобильных Android приложений (ч...metaform
 
MVP, Moxy. Как правильно пользоваться
MVP, Moxy. Как правильно пользоватьсяMVP, Moxy. Как правильно пользоваться
MVP, Moxy. Как правильно пользоватьсяYuri Shmakov
 
Модульное тестирование с помощью visual studio 2012 MS Test, Nunit, X-unit.ne...
Модульное тестирование с помощью visual studio 2012 MS Test, Nunit, X-unit.ne...Модульное тестирование с помощью visual studio 2012 MS Test, Nunit, X-unit.ne...
Модульное тестирование с помощью visual studio 2012 MS Test, Nunit, X-unit.ne...Александр Шамрай
 
JavaScript Базовый. Занятие 09.
JavaScript Базовый. Занятие 09.JavaScript Базовый. Занятие 09.
JavaScript Базовый. Занятие 09.Igor Shkulipa
 
C# Web. Занятие 11.
C# Web. Занятие 11.C# Web. Занятие 11.
C# Web. Занятие 11.Igor Shkulipa
 
Moxy. Как правильно пользоваться? / Юрий Шмаков (Arello Mobile)
Moxy. Как правильно пользоваться? / Юрий Шмаков (Arello Mobile)Moxy. Как правильно пользоваться? / Юрий Шмаков (Arello Mobile)
Moxy. Как правильно пользоваться? / Юрий Шмаков (Arello Mobile)Ontico
 
Диагностика проблем в промышленной среде с помощью Intelli Trace и Visual Stu...
Диагностика проблем в промышленной среде с помощью Intelli Trace и Visual Stu...Диагностика проблем в промышленной среде с помощью Intelli Trace и Visual Stu...
Диагностика проблем в промышленной среде с помощью Intelli Trace и Visual Stu...Александр Шамрай
 
Dependency Injection на примере Unity и NInject
Dependency Injection на примере Unity и NInjectDependency Injection на примере Unity и NInject
Dependency Injection на примере Unity и NInjectakrakovetsky
 
Введение в тестирование с использованием закодированных автоматических тестов...
Введение в тестирование с использованием закодированных автоматических тестов...Введение в тестирование с использованием закодированных автоматических тестов...
Введение в тестирование с использованием закодированных автоматических тестов...Александр Шамрай
 
Moxy. Из чего состоит и как этим пользоваться
Moxy. Из чего состоит и как этим пользоватьсяMoxy. Из чего состоит и как этим пользоваться
Moxy. Из чего состоит и как этим пользоватьсяYuri Shmakov
 
Модульная структура
Модульная структураМодульная структура
Модульная структураDenis Tsvettsih
 
The Old New ASP.NET
The Old New ASP.NETThe Old New ASP.NET
The Old New ASP.NETVitaly Baum
 
Role based access-control
Role based access-controlRole based access-control
Role based access-controlAlex Frolov
 
Google I/O 2016 для разработчиков
Google I/O 2016 для разработчиковGoogle I/O 2016 для разработчиков
Google I/O 2016 для разработчиковWOX APP
 
Разработка оптимального ПО - создание раскадровок и сбор отзывов от заинтерес...
Разработка оптимального ПО - создание раскадровок и сбор отзывов от заинтерес...Разработка оптимального ПО - создание раскадровок и сбор отзывов от заинтерес...
Разработка оптимального ПО - создание раскадровок и сбор отзывов от заинтерес...Александр Шамрай
 
Человекопонятные отчёты
Человекопонятные отчётыЧеловекопонятные отчёты
Человекопонятные отчётыbearoff
 
Визулизация ветвления и объединения в Visual Studio Team Foundation Server 2012
Визулизация ветвления и объединения в Visual Studio Team Foundation Server 2012Визулизация ветвления и объединения в Visual Studio Team Foundation Server 2012
Визулизация ветвления и объединения в Visual Studio Team Foundation Server 2012Александр Шамрай
 

La actualidad más candente (20)

FFCMS - вводная для пользователя
FFCMS - вводная для пользователяFFCMS - вводная для пользователя
FFCMS - вводная для пользователя
 
Moxy – реализация MVP под Android. С щепоткой магии
Moxy – реализация MVP под Android. С щепоткой магииMoxy – реализация MVP под Android. С щепоткой магии
Moxy – реализация MVP под Android. С щепоткой магии
 
Объять необъятное, или как использовать несколько MVVM фреймворков в одном XA...
Объять необъятное, или как использовать несколько MVVM фреймворков в одном XA...Объять необъятное, или как использовать несколько MVVM фреймворков в одном XA...
Объять необъятное, или как использовать несколько MVVM фреймворков в одном XA...
 
Создание графического интерфейса пользователя мобильных Android приложений (ч...
Создание графического интерфейса пользователя мобильных Android приложений (ч...Создание графического интерфейса пользователя мобильных Android приложений (ч...
Создание графического интерфейса пользователя мобильных Android приложений (ч...
 
MVP, Moxy. Как правильно пользоваться
MVP, Moxy. Как правильно пользоватьсяMVP, Moxy. Как правильно пользоваться
MVP, Moxy. Как правильно пользоваться
 
Модульное тестирование с помощью visual studio 2012 MS Test, Nunit, X-unit.ne...
Модульное тестирование с помощью visual studio 2012 MS Test, Nunit, X-unit.ne...Модульное тестирование с помощью visual studio 2012 MS Test, Nunit, X-unit.ne...
Модульное тестирование с помощью visual studio 2012 MS Test, Nunit, X-unit.ne...
 
JavaScript Базовый. Занятие 09.
JavaScript Базовый. Занятие 09.JavaScript Базовый. Занятие 09.
JavaScript Базовый. Занятие 09.
 
C# Web. Занятие 11.
C# Web. Занятие 11.C# Web. Занятие 11.
C# Web. Занятие 11.
 
Moxy. Как правильно пользоваться? / Юрий Шмаков (Arello Mobile)
Moxy. Как правильно пользоваться? / Юрий Шмаков (Arello Mobile)Moxy. Как правильно пользоваться? / Юрий Шмаков (Arello Mobile)
Moxy. Как правильно пользоваться? / Юрий Шмаков (Arello Mobile)
 
Диагностика проблем в промышленной среде с помощью Intelli Trace и Visual Stu...
Диагностика проблем в промышленной среде с помощью Intelli Trace и Visual Stu...Диагностика проблем в промышленной среде с помощью Intelli Trace и Visual Stu...
Диагностика проблем в промышленной среде с помощью Intelli Trace и Visual Stu...
 
Dependency Injection на примере Unity и NInject
Dependency Injection на примере Unity и NInjectDependency Injection на примере Unity и NInject
Dependency Injection на примере Unity и NInject
 
Введение в тестирование с использованием закодированных автоматических тестов...
Введение в тестирование с использованием закодированных автоматических тестов...Введение в тестирование с использованием закодированных автоматических тестов...
Введение в тестирование с использованием закодированных автоматических тестов...
 
Moxy. Из чего состоит и как этим пользоваться
Moxy. Из чего состоит и как этим пользоватьсяMoxy. Из чего состоит и как этим пользоваться
Moxy. Из чего состоит и как этим пользоваться
 
Модульная структура
Модульная структураМодульная структура
Модульная структура
 
The Old New ASP.NET
The Old New ASP.NETThe Old New ASP.NET
The Old New ASP.NET
 
Role based access-control
Role based access-controlRole based access-control
Role based access-control
 
Google I/O 2016 для разработчиков
Google I/O 2016 для разработчиковGoogle I/O 2016 для разработчиков
Google I/O 2016 для разработчиков
 
Разработка оптимального ПО - создание раскадровок и сбор отзывов от заинтерес...
Разработка оптимального ПО - создание раскадровок и сбор отзывов от заинтерес...Разработка оптимального ПО - создание раскадровок и сбор отзывов от заинтерес...
Разработка оптимального ПО - создание раскадровок и сбор отзывов от заинтерес...
 
Человекопонятные отчёты
Человекопонятные отчётыЧеловекопонятные отчёты
Человекопонятные отчёты
 
Визулизация ветвления и объединения в Visual Studio Team Foundation Server 2012
Визулизация ветвления и объединения в Visual Studio Team Foundation Server 2012Визулизация ветвления и объединения в Visual Studio Team Foundation Server 2012
Визулизация ветвления и объединения в Visual Studio Team Foundation Server 2012
 

Destacado

Which Coil Spring Is Right For You
Which Coil Spring Is Right For YouWhich Coil Spring Is Right For You
Which Coil Spring Is Right For YouSuperior Engineering
 
Five Years of Spencer Ogden
Five Years of Spencer OgdenFive Years of Spencer Ogden
Five Years of Spencer OgdenTiffany Bowers
 
Презентация Анны Подгорной. II HR- конференция "Будущее за теми, Кто". 4.02.2...
Презентация Анны Подгорной. II HR- конференция "Будущее за теми, Кто". 4.02.2...Презентация Анны Подгорной. II HR- конференция "Будущее за теми, Кто". 4.02.2...
Презентация Анны Подгорной. II HR- конференция "Будущее за теми, Кто". 4.02.2...Zhyvoe Delo, Consulting Group
 
Интерактивная Викторина Intel
Интерактивная Викторина IntelИнтерактивная Викторина Intel
Интерактивная Викторина IntelOlga Bass
 
3. понимание природы хз и ее причины
3. понимание природы хз и ее причины3. понимание природы хз и ее причины
3. понимание природы хз и ее причиныMaksym Balaklytskyi
 
презентация 3. антон лузан - subscribe pro - email-маркетинг для интернет-м...
презентация 3.   антон лузан - subscribe pro - email-маркетинг для интернет-м...презентация 3.   антон лузан - subscribe pro - email-маркетинг для интернет-м...
презентация 3. антон лузан - subscribe pro - email-маркетинг для интернет-м...Евгений Алексеев
 
аспекты
аспектыаспекты
аспектыDrofaUral
 
Проблема йоддефицита (2)
 Проблема йоддефицита (2) Проблема йоддефицита (2)
Проблема йоддефицита (2)userstudioino
 
HAKU PÄÄTTYNYT Lead Sales Manager Hotel Klaus K (e)
HAKU PÄÄTTYNYT Lead Sales Manager Hotel Klaus K (e)HAKU PÄÄTTYNYT Lead Sales Manager Hotel Klaus K (e)
HAKU PÄÄTTYNYT Lead Sales Manager Hotel Klaus K (e)Antti Rotko
 
Web-Based Automated Well Permitting
Web-Based Automated Well PermittingWeb-Based Automated Well Permitting
Web-Based Automated Well PermittingMark Bentley
 
Myths and Misconceptions about Screening for Vapor Migration in Phase Is
Myths and Misconceptions about Screening for Vapor Migration in Phase IsMyths and Misconceptions about Screening for Vapor Migration in Phase Is
Myths and Misconceptions about Screening for Vapor Migration in Phase IsEDR
 
Emil nava
Emil navaEmil nava
Emil navaebunawo
 
Evaluación Geometría
Evaluación Geometría Evaluación Geometría
Evaluación Geometría Alma Alvizo
 

Destacado (20)

PIRÓ ORFEBRES, S.L.
PIRÓ ORFEBRES, S.L.PIRÓ ORFEBRES, S.L.
PIRÓ ORFEBRES, S.L.
 
Which Coil Spring Is Right For You
Which Coil Spring Is Right For YouWhich Coil Spring Is Right For You
Which Coil Spring Is Right For You
 
Five Years of Spencer Ogden
Five Years of Spencer OgdenFive Years of Spencer Ogden
Five Years of Spencer Ogden
 
Презентация Анны Подгорной. II HR- конференция "Будущее за теми, Кто". 4.02.2...
Презентация Анны Подгорной. II HR- конференция "Будущее за теми, Кто". 4.02.2...Презентация Анны Подгорной. II HR- конференция "Будущее за теми, Кто". 4.02.2...
Презентация Анны Подгорной. II HR- конференция "Будущее за теми, Кто". 4.02.2...
 
Интерактивная Викторина Intel
Интерактивная Викторина IntelИнтерактивная Викторина Intel
Интерактивная Викторина Intel
 
3. понимание природы хз и ее причины
3. понимание природы хз и ее причины3. понимание природы хз и ее причины
3. понимание природы хз и ее причины
 
презентация 3. антон лузан - subscribe pro - email-маркетинг для интернет-м...
презентация 3.   антон лузан - subscribe pro - email-маркетинг для интернет-м...презентация 3.   антон лузан - subscribe pro - email-маркетинг для интернет-м...
презентация 3. антон лузан - subscribe pro - email-маркетинг для интернет-м...
 
аспекты
аспектыаспекты
аспекты
 
Проблема йоддефицита (2)
 Проблема йоддефицита (2) Проблема йоддефицита (2)
Проблема йоддефицита (2)
 
London Brochure
London BrochureLondon Brochure
London Brochure
 
Watch Me Install Alfresco
Watch Me Install AlfrescoWatch Me Install Alfresco
Watch Me Install Alfresco
 
Transport
TransportTransport
Transport
 
8. tüdőbeteg kórlap
8. tüdőbeteg kórlap8. tüdőbeteg kórlap
8. tüdőbeteg kórlap
 
HAKU PÄÄTTYNYT Lead Sales Manager Hotel Klaus K (e)
HAKU PÄÄTTYNYT Lead Sales Manager Hotel Klaus K (e)HAKU PÄÄTTYNYT Lead Sales Manager Hotel Klaus K (e)
HAKU PÄÄTTYNYT Lead Sales Manager Hotel Klaus K (e)
 
Web-Based Automated Well Permitting
Web-Based Automated Well PermittingWeb-Based Automated Well Permitting
Web-Based Automated Well Permitting
 
Materia y energia
Materia y energiaMateria y energia
Materia y energia
 
Myths and Misconceptions about Screening for Vapor Migration in Phase Is
Myths and Misconceptions about Screening for Vapor Migration in Phase IsMyths and Misconceptions about Screening for Vapor Migration in Phase Is
Myths and Misconceptions about Screening for Vapor Migration in Phase Is
 
Emil nava
Emil navaEmil nava
Emil nava
 
AVTOKOZMETIKA BROŠURA
AVTOKOZMETIKA BROŠURAAVTOKOZMETIKA BROŠURA
AVTOKOZMETIKA BROŠURA
 
Evaluación Geometría
Evaluación Geometría Evaluación Geometría
Evaluación Geometría
 

Similar a Enterprise flex pure mvc, slides, russian

UAFPUG6 - PureMVC
UAFPUG6 - PureMVCUAFPUG6 - PureMVC
UAFPUG6 - PureMVCmandrew182
 
Uafpug 8 Presentation Puremvc Papervision Gallery Kuriksha Dmitry
Uafpug 8 Presentation Puremvc Papervision Gallery Kuriksha DmitryUafpug 8 Presentation Puremvc Papervision Gallery Kuriksha Dmitry
Uafpug 8 Presentation Puremvc Papervision Gallery Kuriksha DmitryMax Rozdobudko
 
#3 "Webpack и Vue.JS: Создание больших приложений и их расширение" Кирилл Кай...
#3 "Webpack и Vue.JS: Создание больших приложений и их расширение" Кирилл Кай...#3 "Webpack и Vue.JS: Создание больших приложений и их расширение" Кирилл Кай...
#3 "Webpack и Vue.JS: Создание больших приложений и их расширение" Кирилл Кай...JSib
 
ASP.NET, MVC, ASP.NET MVC
ASP.NET, MVC, ASP.NET MVCASP.NET, MVC, ASP.NET MVC
ASP.NET, MVC, ASP.NET MVCGetDev.NET
 
C# Desktop. Занятие 08.
C# Desktop. Занятие 08.C# Desktop. Занятие 08.
C# Desktop. Занятие 08.Igor Shkulipa
 
Антон Валюх - Использование паттерна Mvvm в android
Антон Валюх - Использование паттерна Mvvm в androidАнтон Валюх - Использование паттерна Mvvm в android
Антон Валюх - Использование паттерна Mvvm в androidDataArt
 
Web deployment
Web deploymentWeb deployment
Web deploymentGetDev.NET
 
Отладка веб-приложений на Javascript
Отладка веб-приложений на JavascriptОтладка веб-приложений на Javascript
Отладка веб-приложений на JavascriptDenis Latushkin
 
Наталья Чуфырина, Mail.Ru Group, «Как создать команду по автоматизации тестир...
Наталья Чуфырина, Mail.Ru Group, «Как создать команду по автоматизации тестир...Наталья Чуфырина, Mail.Ru Group, «Как создать команду по автоматизации тестир...
Наталья Чуфырина, Mail.Ru Group, «Как создать команду по автоматизации тестир...Mail.ru Group
 
Symfony2 practice
Symfony2 practiceSymfony2 practice
Symfony2 practiceSkorney
 
Шаблоны проектирования в Magento
Шаблоны проектирования в MagentoШаблоны проектирования в Magento
Шаблоны проектирования в MagentoPavel Usachev
 
Костянтин Чаус — Monitoring of huge Drupal site. Tools and tips
Костянтин Чаус — Monitoring of huge Drupal site. Tools and tipsКостянтин Чаус — Monitoring of huge Drupal site. Tools and tips
Костянтин Чаус — Monitoring of huge Drupal site. Tools and tipsLEDC 2016
 
Создание повторно используемых бизнес моделей с помощью технологии Domain Com...
Создание повторно используемых бизнес моделей с помощью технологии Domain Com...Создание повторно используемых бизнес моделей с помощью технологии Domain Com...
Создание повторно используемых бизнес моделей с помощью технологии Domain Com...GetDev.NET
 
Yury Glushkov.What should we build a website.Drupal Camp Kyiv 2011
Yury Glushkov.What should we build a website.Drupal Camp Kyiv 2011Yury Glushkov.What should we build a website.Drupal Camp Kyiv 2011
Yury Glushkov.What should we build a website.Drupal Camp Kyiv 2011camp_drupal_ua
 
Java осень 2012 лекция 9
Java осень 2012 лекция 9Java осень 2012 лекция 9
Java осень 2012 лекция 9Technopark
 
Drupal организация разработки
Drupal   организация разработкиDrupal   организация разработки
Drupal организация разработкиAnna Fedoruk
 

Similar a Enterprise flex pure mvc, slides, russian (20)

Devtools
DevtoolsDevtools
Devtools
 
UAFPUG6 - PureMVC
UAFPUG6 - PureMVCUAFPUG6 - PureMVC
UAFPUG6 - PureMVC
 
Uafpug 8 Presentation Puremvc Papervision Gallery Kuriksha Dmitry
Uafpug 8 Presentation Puremvc Papervision Gallery Kuriksha DmitryUafpug 8 Presentation Puremvc Papervision Gallery Kuriksha Dmitry
Uafpug 8 Presentation Puremvc Papervision Gallery Kuriksha Dmitry
 
PureMVC and Papervision
PureMVC and PapervisionPureMVC and Papervision
PureMVC and Papervision
 
MWWM
MWWMMWWM
MWWM
 
#3 "Webpack и Vue.JS: Создание больших приложений и их расширение" Кирилл Кай...
#3 "Webpack и Vue.JS: Создание больших приложений и их расширение" Кирилл Кай...#3 "Webpack и Vue.JS: Создание больших приложений и их расширение" Кирилл Кай...
#3 "Webpack и Vue.JS: Создание больших приложений и их расширение" Кирилл Кай...
 
Сервлеты
СервлетыСервлеты
Сервлеты
 
ASP.NET, MVC, ASP.NET MVC
ASP.NET, MVC, ASP.NET MVCASP.NET, MVC, ASP.NET MVC
ASP.NET, MVC, ASP.NET MVC
 
C# Desktop. Занятие 08.
C# Desktop. Занятие 08.C# Desktop. Занятие 08.
C# Desktop. Занятие 08.
 
Антон Валюх - Использование паттерна Mvvm в android
Антон Валюх - Использование паттерна Mvvm в androidАнтон Валюх - Использование паттерна Mvvm в android
Антон Валюх - Использование паттерна Mvvm в android
 
Web deployment
Web deploymentWeb deployment
Web deployment
 
Отладка веб-приложений на Javascript
Отладка веб-приложений на JavascriptОтладка веб-приложений на Javascript
Отладка веб-приложений на Javascript
 
Наталья Чуфырина, Mail.Ru Group, «Как создать команду по автоматизации тестир...
Наталья Чуфырина, Mail.Ru Group, «Как создать команду по автоматизации тестир...Наталья Чуфырина, Mail.Ru Group, «Как создать команду по автоматизации тестир...
Наталья Чуфырина, Mail.Ru Group, «Как создать команду по автоматизации тестир...
 
Symfony2 practice
Symfony2 practiceSymfony2 practice
Symfony2 practice
 
Шаблоны проектирования в Magento
Шаблоны проектирования в MagentoШаблоны проектирования в Magento
Шаблоны проектирования в Magento
 
Костянтин Чаус — Monitoring of huge Drupal site. Tools and tips
Костянтин Чаус — Monitoring of huge Drupal site. Tools and tipsКостянтин Чаус — Monitoring of huge Drupal site. Tools and tips
Костянтин Чаус — Monitoring of huge Drupal site. Tools and tips
 
Создание повторно используемых бизнес моделей с помощью технологии Domain Com...
Создание повторно используемых бизнес моделей с помощью технологии Domain Com...Создание повторно используемых бизнес моделей с помощью технологии Domain Com...
Создание повторно используемых бизнес моделей с помощью технологии Domain Com...
 
Yury Glushkov.What should we build a website.Drupal Camp Kyiv 2011
Yury Glushkov.What should we build a website.Drupal Camp Kyiv 2011Yury Glushkov.What should we build a website.Drupal Camp Kyiv 2011
Yury Glushkov.What should we build a website.Drupal Camp Kyiv 2011
 
Java осень 2012 лекция 9
Java осень 2012 лекция 9Java осень 2012 лекция 9
Java осень 2012 лекция 9
 
Drupal организация разработки
Drupal   организация разработкиDrupal   организация разработки
Drupal организация разработки
 

Enterprise flex pure mvc, slides, russian

  • 1. Flex Pure MVC архитектура для приложений enterprise уровня Sergiy Shychynov (EPAM) 2012-03-24
  • 2. Содержание 1. Сначала мы вспомним основные составляющие микроахитектуры PureMVC. 2. Далее рассмотрим структуру и задачи, возникающие при использовании PureMVC в больших проектах. 1. Разновидности и жизненный цикл элементов системы 2. Необходимость синхронизации работы медиаторов с асинхронно создаваемыми видимыми элементами. 3. «Страничная» архитектура для PureMVC проекта: 1. Управление View компонентами в «страничной» архитектуре: 1. Отложенное (deferred) создание, 2. Расположение в иерархии Display Objects. 2. Жизненный цикл «страницы», дескриптор «страницы» 3. Прелоадер страницы 4. Использование модулей в «страничной» архитектуре.
  • 3. Основные составляющие PureMVC используя презентацию Samuel Asher Rivello) http://www.adobe.com/newsletters/inspire/december20 08/articles/article6/index.html MVC in PureMVC
  • 4.
  • 5. Схема взаимодействия компонентов PureMVC для выполнения элементарной операции  Внешний вид компонента Hello Google – кнопка и текстовое поле для сообщения  Последовательность элементарных действий выполняемых при нажатии кнопки  Положение этих действий на диаграмме PureMVC
  • 6.
  • 7. Основные задачи, возникающие при использовании PureMVC в больших проектах. «Приложение enterprise уровня» - БОЛЬШИЕ БОЛЬШОЕ количество РАЗНЫХ форм и компонентов, которые необходимо будет использовать в разных ситуациях и в разное время Речи о том, что все элементы будут созданы одновременно или заранее быть не может. Более того – было бы неплохо, чтобы и грузить их все сразу не требовалось. Рассмотрим несколько разных «видов» гипотетического большого приложения.
  • 8. Форма - Списки контактов и контактных групп
  • 12. Форма – Редактирование конвейера операций маппинг процессора для бла-бла-бла
  • 13. Форма – Маппинг полей метода сервиса передачи телефонных сообщений.
  • 15. Среди всего UI большого приложения можно выделить элементы (подсистемы) 1. постоянно находятся на экране и доступны для взаимодействия. 2. могут вызываться пользователем на экран по желанию и ведут себя относительно независимо от других элементов UI. 3. которые имеют отношение к текущей операции, выполняемой пользователем, показываются на экране когда он начинает выполнять эту операцию и будут убраны с экрана когда он эту операцию завершит. Причем таких циклов появления и исчезновения с экрана может быть много. Этот третий тип подсистем мы будем в дальнейшем называть страницами – Pages. И если операции по обслуживанию жизненного цикла для 1 и 2 типа можно выполнить один раз (например в StartupCommand), то выполнение всех нижеперечисленных действий для компонентов подсистем 3-его типа является рутинной операцией и нуждается в автоматизации.
  • 16. Жизненный цикл элементов системы и основные операции над ними. 1. создать и разместить в иерархии DisplayObjects необходимые компоненты - ViewComponents. 2. создать и зарегистрировать необходимые медиаторы – Mediators. 3. связать медиаторы с соответствующими компонентами ссылки на компоненты, прослушивание события от компонентов 4. зарегистрировать необходимые для работы подсистемы команды – Commands 5. создать и зарегистрировать необходимые для работы прокси – Proxy, 6. отобразить в компонентах валидные данные 1. загружаются с сервера - определенное время 2. загружаются с сервера – «ошибки технические» 3. политики безопасности – запрещено смотреть данные – «ошибки логические» 4. Не стоит показывать на экране новые компоненты, еще не заполненные данными, до того как эти данные будут получены с сервера. 5. Это процесс мы будем называть предзагрузка – preloader. 7. основной цикл работы – стандартный 1. Отдельный вопрос – это обработка ошибок (серверных). Бывают устранимые и неустранимые ошибки – остаемся на странице, обновляем или покидаем ее. 8. после завершения операции - корректно освободить ресурсы системы от текущей «страницы» 1. Отписывание медиаторов от событий, которые они прослушивали от компонентов. 2. Удаление «актеров» PureMVC (медиаторов) 1. «отписать» медиаторы от системы (unregister) 2. удалять медиаторы или сохранять их в «кэше» 3. команды тоже можно «отписать» от системы, 4. прокси отписывать от системы и удалять – как правило не нужно и даже вредно. 3. Удаление видимых компонентов - операция создания компонента и добавления его в DisplayList более ресурсоемкая, чем сделать невидимый компонент – видимым. НЕ удалять а делать невидимыми 4. Очистить ссылки на временные данные - Garbage Collector освободит память.
  • 17. Необходимость синхронизации работы медиаторов с асинхронно создаваемыми видимыми элементами.  Как известно видимые элементы – компоненты флекса не создаются мгновенно по запросу. Как правил от момента создание экземпляра компонента, установки его свойств и добавления его в иерархию DisplayObjects проходит некоторое время и несколько этапов, прежде чем событие «creationComplete» дает нам знать, что компонент и все его подкомпоненты полностью созданы и готовы к работе.  До этого момента медиатор, даже если и будет иметь ссылку на компонент, не сможет полноценно с ним работать.  DefferedMediator - решает проблему асинхронного создания компонентов. Откладывает вызовы initialize и activate до момента, когда компонент будет создан и инициализирован. А потом еще откладывает update до момента, когда все медиаторы из списка будут активированы.
  • 18. DefferedMediator  constructor() – чистый конструктор  create(); - все что хотелось сделать в конструкторе  initialize(); - в том числе addViewListeners уровня инициализации  activate(); - в том числе addViewListeners уровня активации waitForMediatorsActivation(mediatorNames);  update(); - основной цикл  deactivate(); – в том числе автоматически удаляет eventListeners уровня активации  finalize(); – в том числе автоматически удаляет eventListeners уровня инициализации
  • 19. Кто, когда и как создает видимые элементы. Медиатор знает класс своего(-их) компонентов. Медиатор знает где должен быть его компонент. SlotViewComponentDescription viewComponentName = "M1“ viewComponentSlot = "SlotAMediator" viewComponent = UIComponent Медиатор-слотхолдер Медиатор-клиент “SlotAMediator” получает M1Mediator создает нотификейшен, адресованный компонент и отправляет его ему и добавляет в свой слот новый компонент под именем слоту "SlotAMediator" - "M1“. просит его хранить под именем "M1“. Обычно в методе create() Слот – это обычно ViewStack или другой контейнер.
  • 21.
  • 22.
  • 23.
  • 24. «Страничная» PureMVC архитектура «Страница» – это некоторое множество компонентов, функционирующих совместно в одном промежутке времени. Эти компоненты и обслуживающие их актеры PureMVC совместно создаются, работают и удаляются. Чтобы не писать отдельные команды для открытия каждой страницы, была создана единая команда открытия новой страницы ViewPageCommand, которая использует PageDescription страницы и работает совместно с Pages Proxy.
  • 25. Основные задачи PagesProxy хранение справочника всех страниц системы function getPageDescription(pageName:String):PageDescription хранение информации о текущей открытой странице (ее имя, дескриптор, стейт, состояние редактирование, helpContext и прочее) Соответственно все страницы имеют уникальные имена public class Pages { public static const ABOUT:String = "about"; public static const ADMIN_EMAIL_TEMPLATE_EDIT:String = "adminEmailTemplateEdit"; public static const DOCUMENT_TRANSLATION:String = "documentTranslation"; … } и дескрипторы
  • 26. PageDescription  pageName:String,  preloader:Class, - клоасс-наследник BasePagePreloader  mediators:Array, - список классов-наследников BaseMediator  proxies:Array = null, - список классов-наследников BaseProxy  commands:Array = null, - список CommandDescription(name:String, commandClass:Class)  stateParams:Object = null, - редко встречающиеся доп. параметры  pageTitle:String = null, } - часто встречающиеся доп. параметры  breadcrumbs:Array = null. … }
  • 27. Вызов ViewPageCommand Регистрация команды facade.registerCommand(BaseNotifications.VIEW_PAGE, ViewPageCommand); Вызов команды активации страницы var params:PageNotificationParams = new PageNotificationParams(); params.pageName = Pages.IMPORT_REPORT; params.id = importReport.id; params.documentType = importReport.dataType; sendNotification(BaseNotifications.VIEW_PAGE, params); PageNotificationParams  var pageName:String;  var pageState:String;  var id:Number;  var backPageName:String;  var preloader:BasePreloaderMediator; - создается и добавляется в процессе открытия
  • 28. Пример дескриптора страницы new PageDescription( Pages.QUESTIONNAIRE, QuestionnaireAnswerPreloader, [QuestionnaireSlotHolderMediator, QuestionnaireAnswerMediator], [QuestionnairesProxy, ProcessEditProxy, ProcessTypesListProxy, TimeScaleProxy], [ new CommandDescription(SPNotification.FIND_NEW_QUEST, LoadQuestiannairCommand), new CommandDescription(SPNotification.UPDATE_ASSET_QUEST, UpdateAssetCommand), ], { questionnaireComponentState: QuestionnaireComponentState.ANSWER }, "Questionnaire Registry" ) Далее описание алгоритма работы ViewPageCommand …
  • 29. pageDescriptor – ищем по имени страницы Проверяет наличие дескриптора страницы stateParams : {} – доп. набором параметров страницы не вошедшие в дескриптор (редко) (если надо грузит нужный модуль) viewParams : PageNotificationParams – параметры страницы, заполняемые при ее открытии (все которые нужны часто) Создает и регистрирует необходимые прокси validate() & Создает и запускает прелоадер load() препроцессинг - - отписывает от системы медиаторы - подчищает «временные» данные + - отписывает медиатор от events Закрывает текущую страницу компонентов Страница не - добавляет прелоадер во viewParams открывается Регистрирует команды Если создаются, то в следующем порядке: - Конструктор Создает (или достает из кеша) медиаторы - Setup params (stateParams и viewParams) - create() Медиаторы должны создать свои компоненты, Активирует медиаторы. разместить их в иерархии DisplayLists, сделать видимыми и подписаться на необходимые events. После активации всех вызывается update()
  • 30. Прелоадер – Preloader Прелоадер загружает несколько «частей» данных (прокси или делегаты). После полной загрузки всех частей возможна их валидация и дополнительная обработка. Если валидатор выдает false, страница не будет открыта - вместо этого будет выведено сообщение об ошибке. Фрагмент кода вызова прелоадера при открытии страницы if(pageDesc.preloader != null) { setLoadingState(true); registerProxies(); // for preloading var preloaderMediator:BasePreloaderMediator = new (pageDesc.preloader)(); preloaderMediator.viewParams = params; preloaderMediator.stateParams = pageDescriptor.stateParam; preloaderMediator.callback = executeAfterPreload; preloaderMediator.load();
  • 31. BasePreloaderMediator  var stateParams:Object;  var viewParams:PageNotificationParams; Override it to create more preloader parts. You can use viewParams and stateParams.  function load():void {  addDelegatePreloaderPart("YYYid", ResourceTypeDelegate.instance.getResourceTypeById(id));  //...  addNotificationPreloaderPart("XXXid", XXXResultNotification, XXXFaultNotification);  xxxProxy.load(blablabla);  //...  activate();  } Override it to validate loaded data. If ERROR - set preloader.errorKey before returning false value.  function validate():Boolean {  if(preloader.errorKey == null) {  // достаем нужное нам данное и проверяем  getPart("YYYid") – используем для проверки  }  return (preloader.errorKey == null);  }
  • 32. Пример прелоадера «детям до 16»  public class ManageGroupMembershipPreloader extends BasePreloaderMediator  {  override public function load():void {  if(!isNaN(id))  addDelegatePreloaderPart(ContactProxy.CONTACT, ContactDelegate.instance.getContactById(id) );   addNotificationPreloaderPart(LanguageProxy.PLAIN_LANGUAGE_LIST,  SPNotification.PLAIN_LANGUAGE_LIST_LOADED, SPNotification.PLAIN_LANGUAGE_LIST_FAILED);  LanguageProxy(facade.retrieveProxy(LanguageProxy.NAME)).getPlainLanguageList();   super.load();  }   override public function validate():Boolean {  if(super.validate()) {  var contact:Contact = getPart(ContactProxy.CONTACT) as Contact;  if(contact != null && contact.age < 16)  setPreloaderError("Просмотр этой страницы не разрешен детям до 16");  return super.validate();  }  }
  • 33. Модульность В настоящее время система имеет:  полторы сотни (150) основных страниц со связанными с ними rollover формами,  несколько десятков popup-форм  некоторое кол-во подсистем,  работающих постоянно на экране,  вызываемых по требованию пользователя  или работающий в качестве «демонов» – daemon (ping, system messages)  и «сервисов» (messages, multiple operations, progress indication etc.) Кодовая база клиентской части проекта включает более 2000 файлов. Из них более 1600 as файлов и около 400 mxml. При этом с точки зрения заказчика это все разбито на 8 логических «модулей» и лицензия на использование каждого из них может покупаться отдельно. Кроме того многие пользователи могут не иметь доступа к некоторым модулям (администрирование, отчеты) по соображениям безопасности или в соответствии с их ролями в системе.
  • 34. Соображения по поводу Модульности Необходимо: при начальной загрузке загружать только ядро системы, а все дополнительные, не всегда или редко используемые возможности подгружать по требованию. Для уменьшения времени загрузки и потребляемого трафика.  RSL для этого использовать нельзя:  приходилось бы вручную выбирать какие классы включать в эту библиотеку а какие - нет  Флексовые модули для этого как бы не задумывались, но воспользоваться ими получилось:  линкер mxmlc при компиляции модуля позволяет собрать все классы, по цепочке зависимостей,  есть возможность указать линкеру, что необходимо исключить классы, которые уже есть в ядре приложения.  «Страничная» организация – основа сборки модуля.  PageDescriptor – это узел для дерева линковки всех классов  модуль подгружает ViewPageCommand в момент когда впервые понадобиться страница содержащаяся в этом модуле  узнает из справочника в каком модуле находится нужная страница (moduleDescriptors.xml )  после загрузки модуля, все PageDescriptors из модуля добавляются в PagesProxy
  • 35. Структура иерархии модулей  Module – единица компиляции и линковки  ModuleDescription – содержит полный набор всех Page Descriptors модуля  PageDescriptionsXXX – логически сгруппированные наборы дескрипторов страниц moduleDescriptors.xml – справочник, содержащий информацию о том какая страница в каком модуле содержится flex-include-vo.xml – список всех VO системы для включения в ядро системы (решение проблемы регистрации VO для ремотинга) Соответствующие ANT скрипты. !!! НИКОГДА не включайте модули из среды Flash Builder!!!
  • 36. public function ModuleMain() { super(); _moduleDescription = new ModuleDescriptionMain(); //NameUtils.registerServerClass(ContactTask); initializeModule(); } public function ModuleDescriptionMain() { super("ModuleMain", [], [] .concat(PageDescriptionsMain.pageDescriptions) .concat(PageDescriptionsContacts.pageDescriptions) .concat(PageDescriptionsReporting.pageDescriptions) ); }
  • 37. public class PageDescriptionsResourcesAssets { public static const commonBreadcrumbs:Array = [Pages.R_A_VIEW_ROOT_RESOURCES]; public static const commonProxies:Array = [ResourceTypeProxy, ParentListProxy, SessionDataProxy,AssetProxy, ProcessEditProxy, ProcessesListProxy ]; public static const pageDescriptions:Array = [///////////////////////////////////////////// new PageDescription(Pages.UPDATE_RESOURCE_TYPE, PageState.ADD_EDIT_VIEW, ResourceTypeEditPreloader, Pages.R_A_VIEW_ROOT_RESOURCES, [ResourcesSlotHolderMediator, ResourceTypeEditMediator], [SessionDataProxy, AssetProxy, ProcessEditProxy], [ new CommandDescription(SPNotification.FIND_ASSET_FOR_DETAILS, LoadAssetCommand), new CommandDescription(SPNotification.FIND_ASSET_FOR_EDIT, LoadAssetEditCommand), ], {accessArea: AccessArea.RESOURCE_TYPES}, commonBreadcrumbs.concat(), "page.updateResourceType.title", "page.updateResourceType.breadcrumbLabel", null ).addAddPageState(null, "page.createResourceType.title", "page.createResourceType.breadcrumbLabel" ).addViewPageState(null, "page.updateResourceType.viewTitle", "page.updateResourceType.viewBreadcrumbLabel" ).addLibraryPageState( Pages.R_A_UPDATE_RESOURCE_TYPE_FOR_LIBRARY ), new PageDescription(Pages.QUESTIONNAIRE, PageState.EDIT_VIEW, QuestionnaireAnswerPreloader, null, [QuestionnaireAnswerMediator], [QuestionnairesProxy, ProcessEditProxy, ProcessTypesListProxy], null, {questionnaireComponentState:QuestionnaireComponentState.ANSWER}, [TreeNodeBase.NODE_BIA] ).registerRollover(Rollovers.QUESTIANNAIRE_RECOVERY_SCHEDULE, PageState.ADD_EDIT_VIEW ).registerRollover(Rollovers.QUESTIONNAIRE_ADD_PROCESS, PageState.ADD_EDIT_VIEW ) ] ///////////////////////////////////////////// }
  • 38. moduleDescriptors.xml  <?xml version="1.0" encoding="UTF-8"?>  <Modules>  <Module name="ModuleMain">  <Pages>  <Page name="about"/>  <Page name="myTasksPage"/>  </Pages>  <Dependencies/>  </Module>  <Module name="ModuleAdministration">  <Pages>  <Page name="adminLogo"/>  <Page name="adminLanguageEditor"/>  <Page name="auditTrail"/>  </Pages>  <Dependencies/>  </Module>  </Modules>
  • 39. Проблема регистрации классов для римотинга. [RemoteClass(alias="com.os.sp.domain.messaging.MessagesGroup")] public class MessagesGroup extends MessagesGroupBase implements IOSSPMessage {} !!! Не регистрирует класс, если VO линкуется через модуль! Решение проблемы: 1) в модуле делаем registerClassAlias(getClassServerName(classRef), classRef); 2) линкуем все VO в ядро системы (flex-include-vo.xml)  <?xml version="1.0"?>  <flex-config>  <includes append="true">  <symbol>com.os.sp.domain.messaging.MessagesGroup</symbol>  <symbol>com.os.sp.domain.messaging.SmsCostConfig</symbol>  <symbol>com.os.sp.domain.integrity.InvalidRecord</symbol>  </includes>  </flex-config>
  • 40. Фрагмент ant-task-а компиляции основного приложения (ядра системы)  <property name="FLEX_INCLUDE_VO_CONFIGURATION" value="${MAIN_SOURCE_FOLDER}/flex-include-vo.xml" />   <mxmlc file="${MAIN_SOURCE_FOLDER}/${ROOT_APPLICATION}.mxml"  output="@{output}.swf"  link-report="${BUILD_FOLDER}/${ROOT_APPLICATION}.${FULL_LINK_REPORT_POSTFIX}"  >  <load-config filename="${FLEX_LOCAL_CONFIGURATION}"/>  </mxmlc>   Компиляция модулей  <target name="compile-modules" if="flex.modular.exist">  <compile-module-simple moduleName="ModuleAdministration" />  <compile-module-simple moduleName="ModuleMessaging" />  <compile-module-simple moduleName="ModuleImportExport" />  </target>   Фрагмент из макроопределения компиляции модуля  <mxmlc file="${MODULE_SOURCE_FOLDER}/@{moduleName}.@{moduleType}"  output="${BUILD_FOLDER}/@{moduleName}.swf"  load-externs="${BUILD_FOLDER}/@{dependsOn}.${FULL_LINK_REPORT_POSTFIX}"  >  </mxmlc>
  • 42. НО
  • 43. ОСТАЛОСЬ НЕ ОХВАЧЕННЫМ Взаимодействие View Components и Mediators  Шаблон «страницы»  Интерфейс «страничного» View Component  Обмен данными между медиатором и View компонентом.  Состояние «редактирования» (Editing state)  Обработка нажатий кнопок (Buttons)  Обработка других команд (пример – Chevrons) …
  • 44. А ТАКЖЕ  Базовые классы медиаторов  Медиатор формы  Медиатор листа  Медиатор попапа  Подсистема Proxy-Delegate-Preloader  Локализация приложений …
  • 45. Приложение: особенности реализации SlotHolder медиаторов  Задача по созданию и связыванию вью компонентов с медиаторами возложена на медиатор.  Медиатору известен класс его компонента. При создании медиатора – в методе create() – медиатор создает инстанс класса вью компонента и отправляет его слот-холдер медиатору чтобы тот поместил его себе в DisplayList.
  • 46. Способы создания и связывани компонента с медиатором.  protected function setupMediator(…)  mediatorName:String = null,  // AUTO – такое же как имя класса – для регистрации в PureMVC   viewComponentReference:Object = null,  // 1) null must be null,  // 2) component class  // 3) component instance (descendant of UIComponent)   viewComponentName:String = null, // viewComponent custom name  // AUTO – по имени медиатора без постфикса Mediator  // будет использовано как id и name в слотхолдере   viewComponentSlot:String = null, // specific slot for register/find viewComponent (if need)   viewComponentInitAction:int = 0 // special init action (0 - no action)  INIT_NONE:int = 0; // no action   INIT_FIND_OR_WAITING_FOR_THE_VIEW_COMPONENT:int = 1;  // find view component with appropriate name in appropriate slot or (in not found)  // listen for the BaseNotifications.SLOT_VIEW_COMPONENT_CREATION_COMPLETE notification   INIT_FIND_VIEW_COMPONENT:int = 2;  // find view component with appropriate name in appropriate slot   INIT_ADD_TO_SLOT:int = 4;  // add view component to appropriate slot using appropriate name
  • 47. Особенности реализации протокола взаимодействия слот-холдер медиаторов с их клиентами.  override public function listNotificationInterests():Array  {  return (slots == null)  ? super.listNotificationInterests()  : super.listNotificationInterests().concat(  BaseNotifications.SLOT_VIEW_COMPONENT_ADD,  BaseNotifications.SLOT_VIEW_COMPONENT_REMOVE_BY_NAME,  BaseNotifications.SLOT_VIEW_COMPONENT_SHOW,  BaseNotifications.SLOT_VIEW_COMPONENT_HIDE,  BaseNotifications.SLOT_VIEW_COMPONENT_FIND  );  }   override public function handleNotification(notification:INotification):void  {  super.handleNotification(notification);  …  }
  • 48. private function defaultSlotHolderNotificationHandler(notification:INotification):void  {  if(slots && slots[notification.getType()]) {  var desc:SlotViewComponentDescription = notification.getBody() as SVCD;  var component:UIComponent;  component = getViewComponentFromSlot(desc.viewComponentSlot, desc.viewComponentName);  switch(notification.getName()) {  case BaseNotifications.SLOT_VIEW_COMPONENT_SHOW:  FlexUIComponentsUtils.showViewComponent(component, true);  break;  case BaseNotifications.SLOT_VIEW_COMPONENT_HIDE:  component.visible = false;  break;  case BaseNotifications.SLOT_VIEW_COMPONENT_ADD:  addViewComponentToInternalSlot(desc);  desc.viewComponent = null; // mark viewComponent as added  break;  case BaseNotifications.SLOT_VIEW_COMPONENT_REMOVE_BY_NAME:  removeViewComponentFromSlotByName(desc);  break;  case BaseNotifications.SLOT_VIEW_COMPONENT_FIND:  desc.viewComponent = component;  break;  }}}
  • 49. Интересный Антипаттерн Далее описан антипаттерн, который используется для оптимизации взаимодействия слотхолдеров. Но мне не стыдно, потому что это, с одной стороны – служит оптимизации (можно было и не делать), с другой – можно было бы без этого обойтись просто воспользовавшись синглтоном-менеджером.  * Register handler for Notification - works just like addEventListebner.  * It doesn't depend on registerMediator/removeMediator !BE AWARE!  function addNotificationListener(notificationName:String, handler:Function):void  {  org.puremvc.as3.core.View.getInstance().registerObserver(notificationName,  new Observer(handler, this) );  }  * Remove Notification handler - works just like removeEventListebner.  * It doesn't depend on registerMediator/removeMediator !BE AWARE!  function removeNotificationListener(notificationName:String):void  {  org.puremvc.as3.core.View.getInstance().removeObserver(notificationName, this );  }
  • 50. Пример использования:  * Try to add view component in appropriate external slot. If there isn't  * appropriate slot then start waiting for SLOT_CREATION_COMPLETE.  function addViewComponentToExternalSlot():void {  var desc:SlotViewComponentDescription = new SlotViewComponentDescription  viewComponentName, viewComponentSlot, viewComponent as UIComponent );   var addNotification:INotification = new Notification(  BaseNotifications.SLOT_VIEW_COMPONENT_ADD, desc, viewComponentSlot);   facade.notifyObservers(addNotification);   if(desc.viewComponent != null) // его бы обнулили если бы он был найден  {  addNotificationListener(BaseNotifications.SLOT_CREATION_COMPLETE,  handleSlotCreationCompleteNotificationToAddViewComponent);  }  }