Iniciando com Cairngorm – Parte 4

Flex / Cairngorm 1 Comment »

A base Cairngorm Event Flow que é tratada na parte 3 é essencial para qualquer aplicação Cairngorm, mas a maioria das aplicações interage com um servidor. O Serviço para trabalhar com o padrão que foi discutido no tutorial anterior é fundamental para este processo. Para aprender e expandir o Cairngorm Flow, você precisa aprender alguns novos elementos do Cairngorm.

O Servidor - Interações e Elementos

Existem três novos tipos de classes que você precisará estar familiarizado com a compreender o pleno Serviço Worker Pattern.

  • ServiceLocator [Referência] - O ServiceLocator é um singleton que contém referências para todos os serviços que a sua aplicação irá utilizar. E geralmente inclui chamadas HTTPService, WebService, ou RemoteObject.
  •  Business Delegate - O Business Delegate tem três funções: para localizar o serviço que é necessário, para efetuar uma chamada para um método sobre o serviço, bem como a rota do resultado para o especificado respondedor. Geralmente, há uns Negócios delegados para cada serviço.
  • Value Object – Value Objects são classes que por definição não exigem qualquer métodos, apenas propriedades. Eles permitem a aplicação transferir dados strongly-typed  complexos do objetos para e do servidor.

Organizando seu projeto Cairngorm (Com Server Interaction)

No último tutorial você viu o padrão da estrutura de um projeto Cairngorm. Para completar esta estrutura, você precisará adicionar duas novas pastas:

  • /business - Esta pasta contém normalmente dois tipos de arquivos: o ServiceLocator (chamado Services.mxml) e Business Delegates.
  • /vo - Esta pasta contém o valor dos objetos que são passados de e para o servidor

Entendendo o processo

Antes de começar a elaborar a interação com servidor para o seu projeto, você precisa entender o pleno Serviço Worker pattern. A Figura 1 ilustra todo o processo.

Full Cairngorm Diagram Final
Figure 1 - Cairngorm Event Flow with Server Interaction

Fase I – Executando

  • O usuário está visualizando um componente que tem um botão login. Quando o botão é clicado, esse componente enviará um evento chamado LoginEvent que se estende do CairngormEvent.
  • O FrontController irá receber o LoginEvent e executar o comando que é mapeado para o evento. Para este exemplo, será nomeado LoginCommand e implementará ICommand.
  • O comando é executado e receberá o LoginEvent como um argumento. O LoginCommand cria uma instância Delegate enquanto passar uma referência ao Responder. O Comando então chama o método especificado no Delegate.
  • O Delegate recebe o serviço do ServiceLocator e convida o método específico sobre o serviço.
  • O serviço definido no ServiceLocator recebe as informações que são passadas para ele a partir da chamada do Delegate.

Phase II – A Aplicação processa a camada
Phase III – Responde

  • O serviço que está definido no ServiceLocator retorna o resultado do processamento do lado do servidor.
  • O Delegate recebe o resultado e passa-o para o responder  especificado.
  • O Responder recebe o resultado indicando um login bem-sucedido.
  • O ModelLocator terá uma constante predefinida para o " Logged in View ". O Responder mudará workflowState para este valor.
  • Desde o ponto de vista é obrigado a workflowState, irá automaticamente atualizar-se para a nova posição.

Nota: Tradicionalmente, o Command e Responder eram da mesma classe em uma aplicação Cairngorm. Se estiver trabalhando com outros desenvolvedores, os pedidos serão provavelmente codificados desta forma. Contudo, a maioria dos desenvolvedores (incluindo Adobe Consulting) estão agora separando estas classes em duas classes diferentes. Pelo menos em um projecto complexo, é possível que não faça sentido para esses itens separados, mas em um grande pedido poderá ser vantajosa na organização e prática para ter duas classes diferentes

O ServiceLocator

O ServiceLocator é um singleton que contém referências para todos os serviços que o pedido será utilizado. Esses serviços podem ser RemoteObjects, HTTPServices, WebServices, personalizado ou serviços. Tal como o FrontController, esta classe é geralmente instanciado no seu arquivo principal da aplicação. Ao contrário de muitos dos outros projetos Cairngorm que você criou, esta classe pode ser definida em MXML (bem como ActionScript). Para definir corretamente esta em MXML, deve haver um namespace que aponta para a pasta business da pasta Cairngorm. Neste caso, o namespace cairngorm é tipicamente usado. O ServiceLocator no Código Exemplo 1 dispõe de um serviço definido, loginService

Actionscript:

  • <?xml version="1.0" encoding="utf-8"?>
  • <cairngorm:ServiceLocator
  •     xmlns:cairngorm="com.adobe.cairngorm.business.*"
  •     xmlns:mx="http://www.adobe.com/2006/mxml">
  •    
  •     <!– Login Service –>
  •     <mx:RemoteObject id="loginService"
  •         showBusyCursor="true"
  •         destination="ColdFusion"
  •         source="CairngormTest.CairngormLogin">
  •        
  •         <mx:method name="login" /> 
  •        
  •     </mx:RemoteObject>
  •    
  • </cairngorm:ServiceLocator>

Code Example 1 - Simples ServiceLocator

O ServiceLocator é normalmente chamado Services.mxml e reside na pasta business do seu projeto Cairngorm
 Comandos com Server Interaction
No último tutorial você hard-coded alguns valores no LoginCommand para verificar se um determinado nome de usuário e senha. Aqui foi o método execute:

Actionscript:

    public function execute(event:CairngormEvent):void {

        var loginEvent:LoginEvent = event as LoginEvent;

        if( (loginEvent.username == "david") && (loginEvent.password == "password")) {

            modelLocator.workflowState = ViewModelLocator.WELCOME_SCREEN;

        }

    }

    Code Example 2 – Comandos com Without Delegate

    Esta metodologia será uma realidade para qualquer comando que não tem interação com o servidor, mas se você tem interação com o servidor, terão de ser modificados para incluir o delegate. Primeiro você terá que tomar uma decisão. Tal como referido anteriormente, você pode ter separado Comandos e respondedores, ou eles podem ser a mesma classe. Para este exemplo, que será a mesma classe. O Comando irá agora também ter necessidade de se implementar a classe mx.rpc.IResponder (observe que com.adobe.cairngorm.business.Responder está obsoleta e deve deixar de ser utilizado).

    A outra alteração inicial é que execute o método agora instanciando uma classe chamada LoginDelegate (que será criado em breve). A classe LoginDelegate exigi um argumento em seu construtor, o Respondedor do serviço. Neste caso, o comando irá funcionar tanto como o comando e a resposta, assim você só precisa inserir a palavra-chave this dentro do parêntese. Se optar por ter um respondedor separado, você iria inserir a referência a ele aqui (em vez da palavra-chave this).

    Actionscript:

    package net.davidtucker.CairngormSample.commands {

       import com.adobe.cairngorm.commands.ICommand;

        import com.adobe.cairngorm.control.CairngormEvent;

        import mx.controls.Alert;

        import mx.rpc.IResponder;

        import net.davidtucker.CairngormSample.business.LoginDelegate;

        import net.davidtucker.CairngormSample.events.LoginEvent;

        import net.davidtucker.CairngormSample.model.ViewModelLocator;

       

        public class LoginCommand implements ICommand,IResponder {

       

            public var modelLocator:ViewModelLocator = ViewModelLocator.getInstance();

           

            public function LoginCommand() {

            }

           

            public function execute(event:CairngormEvent):void {

                var loginEvent:LoginEvent = event as LoginEvent;

                var delegate:LoginDelegate = new LoginDelegate( this );

                delegate.login(loginEvent.loginAttempt);

            }

           

            public function result( event:Object ):void {

                if(event.result == true) {

                    modelLocator.workflowState = ViewModelLocator.WELCOME_SCREEN;

                } else {

                    mx.controls.Alert.show("Password Incorrect","ERROR");

                }

            }

           

            public function fault( event:Object ):void {

                trace("Service Error");

            }

           

        }

    }

    Code Example 3 - Command with Server Interaction Through a Delegate

    Value Objects

    O Value Object não prorrogar ou implementa qualquer classe Cairngorm. Tal como referido anteriormente, ele simplesmente é uma classe que só é obrigado a ter propriedades, mas não métodos. Por exemplo, se você criou um Value Object para uma entrada - ele teria uma propriedade de um nome de usuário e senhaActionscript:

     

    package net.davidtucker.CairngormSample.vo {

        [RemoteClass(alias="CairngormTest.LoginVO")]

        public class LoginVO {

            public var username:String;

            public var password:String;

            public function LoginVO(username:String,password:String) {

                this.username = username;

                this.password = password;

            }

        }

    }

    Code Example 4 - Value Object for Login

    A metatag RemoteClass é importante notar. Esta permitirá o correspondente objeto server-side  (Componente do ColdFusion, classe PHP, Classe de Java, etc…) Para ser mapeado para este Valor de Objeto. Neste caso, é mapeado para um componente do ColdFusion chamado LoginVO no pasta  CairngormTest..
    Business Delegates
    O padrão de projeto final na Micro-Arquitetura do Cairngorm é o Business Delegate. Uns Business Delegate essencialmente é a camada de abstração entre seus serviços e o resto da sua aplicação. Como declarado anteriormente, tem três funções. Primeiras, o Business Delegate localizará o serviço que é necessário no ServiceLocator. Segundo, solicitará um método de serviço. Finalmente, ele criará uma rota de resposta que volta para o responder especificado (normalmente ou um comando responder separado).
    Uma classe Delegada não estende ou implementa classes Cairngorm, mas ela geralmente segue as seguintes diretrizes.

    •          O Delegate tem pelo menos duas propriedades: Uma chamada serviço o qual é uma referência para um serviço no ServiceLocator e um chamado responder que é a resposta para as chamadas de serviço.
    •          Existe um método para cada método server-side que você estará chamando.
    •          Ambos o responder e as variáveis de serviço são fixadas no construtor.

    Actionscript:

    package net.davidtucker.CairngormSample.business {

       

        import mx.rpc.IResponder;

        import net.davidtucker.CairngormSample.vo.LoginVO;

        import com.adobe.cairngorm.business.ServiceLocator;

       

        public class LoginDelegate {

            private var responder : IResponder;

            private var service : Object;   

           

            public function LoginDelegate( responder:IResponder ) {

                this.responder = responder;

                this.service = ServiceLocator.getInstance().getRemoteObject("loginService");

            }

           

            public function login(login:LoginVO):void {

                var call:Object = service.login( login );

                call.addResponder( responder );

            }

           

        }

    }

    Code Example 5 - Service Delegate

    Existem muitos benefícios em ter esta camada. Se codificada corretamente, você deve ser capaz de mudar a interação de servidor (indo de PHP até ColdFusion por exemplo) e só ter que mudar o código em seu ServiceLocator e seu Delegate. Você também pode facilmente inserir "stub code" simular a interação de servidor real durante as primeiras fases de desenvolvimento.
    The Application Tier
    Neste exemplo, a Camada de Aplicação será lidada por uma instalação do ColdFusion 8. Conterá dois componentes de Coldfusion. Estes componentes são propositadamente simples.

    1. LoginVO.cfc - Este componente corresponderá a classe ActionScript LoginVO que você criou anteriormente.
    2. CairngormLogin.cfc - Este componente apresentará o processo de login atual.

    Neste exemplo, A aplicação Flex passará por um objeto LoginVO ActionScript para o método login do CairngormLogin.cfc por uma chamada RemoteObject. Isto será mapeado para um objeto de LoginVO.cfc. Se este objeto LoginVO.cfc tem o username "David" e a senha de "password" o método retornará true. Se não, retornará false.

    Coldfusion:

    <cfcomponent displayname="LoginVO" hint="Login VO For CairngormTest" output="false">

     

        <cfset this.username = "" />

        <cfset this.password = "" />

       

    </cfcomponent>

    Code Example 6 - LoginVO.cfc

    Coldfusion:

    <cfcomponent displayname="CairngormLogin" hint="CFC to Test Cairngorm Service Interaction" output="false">

        <cffunction name="login" displayname="login" access="remote" output="false" returntype="boolean">

            <cfargument name="loginAttempt" type="LoginVO" required="true" />

                <cfif (loginAttempt.username EQ "david") AND (loginAttempt.password EQ "password")>

                    <cfreturn true />

                <cfelse>

                    <cfreturn false />

                </cfif>

        </cffunction>

    </cfcomponent>

    Code Example 7 - CairngormLogin.cfc

Iniciando com Cairngorm – Parte 3

Flex / Cairngorm, Flex Builder 1 Comment »

Agora que você tem isolados dois elementos específicos do Micro-Arquitetura Cairngorm, vamos agora criar uma aplicação mais completa. Até agora os tutoriais abrangeo apenas um design pattern, o ModelLocator, mas agora você será apresentado ao elemento mais determinante do Cairngorm, o Serviço ao Trabalhar com design padrão. A explicação deste padrão será em dois tutoriais. Este tutorial destina-se a cobrir o fluxo básico dentro de uma aplicação Cairngorm, bem como o próximo tutorial será expandida para incluir este fluxo servidor interação. No entanto, antes que você possa aplicar adequadamente este projeto padrão você precisa aprender sobre a organização de um projecto Cairngorm

Organizando um projeto Cairngorm

Uma das tarefas envolvidas com o projeto é qualquer organização. Ao trabalhar com outros desenvolvedores, esta se torna extremamente importante. Normalmente, um projeto Cairngorm é organizado da seguinte forma:

Existe um arquivo Main.mxml que é a aplicação principal para o Cairngorm.
• Os arquivos do projeto estão contidos em uma pasta que usa o formato ” reverse-dns “. Por exemplo, se o projecto foi nomeado CairngormSample, gostaria de utilizar as seguintes pastas net / davidtucker / CairngormSample.
• Dentro do diretório CairngormSample, haverá as seguintes pastas (haverá outras pastas adicionado no próximo tutorial).

  • event/ - Este diretório mantém todos os eventos personalizados para a aplicação
  • control/ - Este diretório é a casa do FrontController para a aplicação
  • commands/ - Este diretório contém os comandos que são chamados pela FrontController
  • model/ - A ModelLocator está contido nesta pasta (e outras classes relacionadas com o model)
  • view/ - Os componentes de view estão contidos neste diretório

Seguindo esse padrão, você pode saber onde encontrar qualquer classe que você pode precisar na sua aplicação Cairngorm. A Figura 1 ilustra esta estrutura de projeto. Ele também é um bom processo de desenvolvimento a ter um padrão estrutura organizacional para seus projetos - mesmo se você não estiver usando Cairngorm
Cairngorm Project Folder
Figure 1 - Cairngorm Project Structure

O serviço para trabalhar com padrão.

O Serviço para Trabalhar com Padrão é o mais difícil para a maioria das pessoas entenderem. Abrange mais da lógica da aplicação Cairngorm. Para compreender este padrão, será necessário compreender algumas das classes que estão incluídas no Cairngorm e seus respectivos efeitos.

CairngormEvent [Referência] - CairngormEvent é central nesse padrão. Trata-se do evento. Para o evento ser tratados adequadamente no Cairngorm, ela terá de ser do tipo CairngormEvent.
CairngormEventDispatcher [Referência] - CairngormEventDispatcher efetivamente as expedições CairngormEvents. É um Singleton (tal como o ModelLocator). Em versões anteriores Cairngorm, que poria esta classe regular, mas agora CairngormEvents pode-se (através do método de expedição). Este método é simplesmente um wrapper para o CairngormEventDispatcher, por isso mesmo se não tiver realmente importado e chamado a classe, ainda é central para o Service to Worker pattern em Cairngorm.
FrontController [Referência] – Os mapas FrontController é um CairngormEvent para um Command.
ICommand [Referência] - Para um comando funcionar corretamente em Cairngorm, ele precisa implementar a interface ICommand. Essa interface exige que um comando terá um método chamado execute e que aceitará o CairngormEvent que é mapeada para ela como um argumento.

O Event Flow do Cairngorm

A forma que essas classes interagem é o Cairngorm Evento Flow. A Figura 2 ilustra todo este processo. Enquanto este processo parece moroso, que segue uma ordem lógica.
Basic Cairngorm Event Flow
Figure 2 - Cairngorm Basic Event Flow
Por exemplo, assumir que a Figura 2 mostra o que acontece quando o usuário clica em um botão login. Tratar-se-ia seguir os seguintes passos

  • O usuário está visualizando um componente que tem um botão login.
  • Quando o botão é clicado, esse componente disparará um evento chamado LoginEvent que se estende CairngormEvent.
  • O FrontController irá receber o LoginEvent e executar o comando que é mapeado para o evento. Para este exemplo, será nomeado LoginCommand e implementará ICommand.
  • O comando é executado e recebeu o LoginEvent como um argumento. O LoginCommand irá alterar o valor workflowState no ModelLocator.
  • O ModelLocator terá uma constante predefinida para o ” Logged in View “. O comando irá mudar workflowState para este valor.
  • Neste ponto a view assumirá workflowState, irá automaticamente atualizar-se para a nova posição.

Depois que esses itens são entendidos, a próxima coisa mais importante para compreender O Cairngorm é: Tudo Deve Ser mapeadas para um evento. Trata-se de um excesso de simplificação drástica, mas é válido em muitas situações. Quando o usuário clica em um botão login - ele deve enviar uma CairngormEvent. Quando o usuário seleciona uma opção de mudar de opinião - ele deve enviar uma CairngormEvent. Quando um usuário envia um formulário para ser armazenado em um banco de dados - o formulário deverá enviar uma CairngormEvent. A expedição de um CairngormEvent conjuntos tudo em movimento

Custom CairngormEvent

A classe CairngormEvent pode ser utilizada dentro de seu projeto, mas na maioria das situações você irá criar seus próprios eventos personalizados que se estendem CairngormEvent (como afirmado anteriormente, de um evento para ser incluído no Cairngorm Event Flow ela deve estender CairngormEvent). Outra razão para criar eventos é personaliza-los para criar propriedades personalizadas do evento, que contêm os dados que você precisa passar para o comando. CairngormEvent tem uma propriedade denominada data (tipo de objeto), que podem conter dados, mas é ideal para ter uma propriedade strongly-typed onde você pode colocar os dados para passar.

Para este exemplo vai criar um evento que corresponde ao exemplo anterior de uma página de login. Este evento terá de cumprir os seguintes critérios:

  • Estender CairngormEvent
  • Ter uma propriedade para o nome de usuário
  • Ter uma propriedade para a senha

Código Exemplo 1 ilustra este evento concluído. Você pode ver que você precisará importar tanto a classe CairngormEvent como a basic Event. Além disso, tal como acontece com todos os eventos, você tem que definir o evento constante. Neste caso, você pode usar LOGIN. As propriedades são definidas abaixo do constante - e eles também são passados para o construtor. A única coisa fora do normal é que você precisa se sobrepor ao método público clone (). Isto é o que o método utiliza o evento para fazer uma cópia de si mesmo. Isto é fundamental no Cairngorm Event Flow. Além disso, para a função de implementar ICommand este método terá de ter um retorno tipo de evento (e não CairngormEvent).

Actionscript:

  • package net.davidtucker.CairngormSample.events {
  •    
  •     import com.adobe.cairngorm.control.CairngormEvent;
  •     import flash.events.Event;
  •    
  •     public class LoginEvent extends CairngormEvent {
  •    
  •         public static const LOGIN:String = “Login”;
  •        
  •         public var username:String;
  •         public var password:String;
  •        
  •         public function LoginEvent(submittedUsername:String,submittedPassword:String) {
  •             username = submittedUsername;
  •             password = submittedPassword;
  •             super(LOGIN);         
  •         }
  •        
  •         override public function clone():Event {
  •             return new LoginEvent(username,password);
  •         }
  •    
  •     }
  • }

Code Example 1 - Custom Event

Comandos

Os comandos dentro de um atual aplicativo Cairngorm “comando” da aplicação. Mesmo no próximo tutorial onde será interagindo com um servidor, o comando ainda fará a maioria dos trabalhos. Neste exemplo, você irá criar um componente que irá receber o nome de usuário e a senha do LoginEvent, verificar os valores contra valores  hard-coded e, em seguida, mudar o workflowState no ModelLocator se os valores estão corretos. O exemplo a seguir executa estas etapas (mas não tem os valores hard-coded incluídos - que serão cobertas no vídeo).

A primeira coisa a notar sobre o código abaixo no Código Exemplo 2 é que o LoginCommand implementa ICommand. Para conseguir isso a classe ICommand também é importado. Além disso, você vai notar o código boilerplate que você usou no passado para trazer no ModelLocator. Para implementar correctamente ICommand, o método execute () também é criado. Ele recebeu um evento do tipo CairngormEvent (tem que ser CairngormEvent e não LoginEvent para implementar correctamente ICommand). Para utilizar corretamente o caso, você precisará fazer um cast com este evento do tipo LoginEvent (o processo de casting será explicado no vídeo). A verdadeira lógica foi deixada fora deste comando, mas você pode ver que as atualizações ModelLocator de view. Depois que a lógica é implementada esta linha de código seria provavelmente colocado dentro de uma condição IF().

Actionscript:

  • package net.davidtucker.CairngormSample.commands {
  •    
  •     import com.adobe.cairngorm.commands.ICommand;
  •     import com.adobe.cairngorm.control.CairngormEvent;
  •     import net.davidtucker.CairngormSample.events.LoginEvent;
  •     import net.davidtucker.CairngormSample.model.ViewModelLocator;
  •        
  •     public class LoginCommand implements ICommand {
  •        
  •         public var modelLocator:ViewModelLocator = ViewModelLocator.getInstance();
  •        
  •         public function LoginCommand() {
  •         }
  •        
  •         public function execute(event:CairngormEvent):void {
  •        
  •             var loginEvent:LoginEvent = event as LoginEvent;
  •            
  •             // COMMAND LOGIC
  •            
  •             modelLocator.workflowState = ViewModelLocator.WELCOME_SCREEN;
  •            
  •         }
  •     }
  • }

Code Example 2 - Cairngorm Command

Controle de Frente (Front Controller)

Tal como referido anteriormente, o FrontController mapeia seus comandos CairngormEvents específicos. Sem isso, o evento jamais se integrará no fluxo Cairngorm. A classe estende FrontController e tem dois métodos: o método constructor e initialize o. O método initialize é onde você irá utilizar o método addCommand para mapear seus eventos de comandos (como se pode ver com o LoginEvent e LoginCommand).

Actionscript:

  • package net.davidtucker.CairngormSample.control {
  •    
  •     import com.adobe.cairngorm.control.FrontController;
  •    
  •     import net.davidtucker.CairngormSample.commands.*;
  •     import net.davidtucker.CairngormSample.events.*;
  •    
  •     public class SampleController extends FrontController {
  •    
  •         public function SampleController() {
  •             this.initialize();
  •         }
  •        
  •         public function initialize():void {
  1.            
  2.             //ADD COMMANDS
  3.             this.addCommand(LoginEvent.LOGIN,LoginCommand);
  4.            
  5.         }
  6.    
  7.     }
  8. }

Code Example 3 - The Cairngorm FrontController

Simplesmente criar um FrontController não é suficiente. Como qualquer classe que tem que ser instanciada dentro de sua aplicação. Código Exemplo 4 ilustra a forma de instanciar seu FrontController no Main.mxml de sua aplicação. Você só precisa adicionar o diretório como um controle XML Namespace e, em seguida, incluir a tag FrontController no arquivo.

mxml:

  • <?xml version=”1.0″ encoding=”utf-8″?>
  • <mx:Application xmlns:mx=”http://www.adobe.com/2006/mxml”
  •     xmlns:control=”net.davidtucker.CairngormSample.control.*”
  •     layout=”absolute”>
  •    
  •     <control:FrontController id=”controller” />
  • </mx:Application>

Code Example 4 - Integrating a FrontController

Agora que você tem visto os elementos básicos de um projeto Cairngorm, você pode realmente construir a amostra de trabalho com o vídeo. Como sempre, o código pedido está abaixo.

Tradução do original inglês: http://www.davidtucker.net

Iniciando com Cairngorm – Parte 2

Flex / Cairngorm 1 Comment »

Part 2 - Usando uma ModelLocator para Gerenciar A View

Nota: Tal como acontece com todos os tutoriais que virão nesta série, esta lição tem duas partes. Em primeiro lugar, no artigo você vai aprender a teoria por trás do tema e, em seguida, no vídeo que você vai fazer um verdadeiro ” code-along “. O artigo dará algumas instruções de como configurar o seu projeto de ” code-along “.

No tutorial anterior você aprendeu as vantagens de usar um ModelLocator para manipular os dados dentro de um aplicativo, no entanto, a vantagem do ModelLocator padrão se estende para além da gestão de dados. Pode manipular a “view” de uma aplicação tão bem. Para ver como funciona na gestão Cairngorm, primeiro você precisa criar um novo projeto chamado “ViewManager” e o nome do arquivo principal aplicação “Main.mxml”. Para este projeto, você também vai necessitar adicionar o Cairngorm.swc para construir o seu projeto (como descrito na parte 1). Também será necessário criar duas novas pastas dentro do “src” pasta: view e model. Quando estiver concluído, o projeto deve ser parecido à Figura 1 abaixo.
Cairngorm Project Window
Figure 1 - ViewManager Project

Em seguida, você precisará ter o código do ModelLocator do tutorial anterior e colocá-lo dentro do seu aplicativo. Já publicamos o código abaixo para sua conveniência.

Actionscript:

  1. package model {
  2.     import com.adobe.cairngorm.model.IModelLocator;
  3.     [Bindable]
  4.     public class ViewModelLocator implements IModelLocator {
  5.         // Single Instance of Our ModelLocator
  6.         private static var instance:ViewModelLocator;
  7.         public function ViewModelLocator(enforcer:SingletonEnforcer) {
  8.         if (enforcer == null) {
  9.                 throw new Error( “You Can Only Have One ViewModelLocator” );
  10.             }
  11.         }
  12.         // Returns the Single Instance
  13.         public static function getInstance() : ViewModelLocator {
  14.             if (instance == null) {
  15.                 instance = new ViewModelLocator( new SingletonEnforcer );
  16.             }
  17.             return instance;
  18.         }
  19.         //DEFINE YOUR VARIABLES HERE
  20.     }
  21. }
  22. // Utility Class to Deny Access to Constructor
  23. class SingletonEnforcer {}

Example 1 - The ModelLocator from Part 1

Se precisar de mais informação sobre a ModelLocator, volte a parte 1 do tutorial.
O único item que deve ser mudado na ModelLocator é a declaração “package”. Para este projeto, ser-lhe-á a colocação ModelLocator na pasta “model”, de modo que o caminho do package simplesmente precisa de mim “model” (ele já foi corrigido acima). Também será necessário adicionar uma variável à sua ModelLocator inicialmente. Esta variável será chamado “workflowState” e será do tipo “uint”. A declaração será semelhante a este:

Actionscript:

  1. public var workflowState:uint = 0;

Example 2 – definindo a variável workflowState
Esta variável será utilizada para “controlar” a view da sua aplicação. A forma mais comum de conseguir isto é usar um ViewStack. Se você não estiver familiarizado com um ViewStack, sinta-se livre para ler esta informação. Um ViewStack tem uma propriedade denominada “selectedIndex”. Este valor numérico que define ” child ” é visível no ViewStack. Considere o seguinte código:

mxml:

  1. <mx:ViewStack id=”myViewStack”>
  2.   <mx:HBox id=”box1″>
  3.     <mx:Label text=”I am Box 1″ />
  4.   </mx:HBox>
  5.   <mx:HBox id=”box2″>
  6.     <mx:Label text=”I am Box 2″ />
  7.   </mx:HBox>
  8.   <mx:HBox id=”box3″>
  9.     <mx:Label text=”I am Box 3″ />
  10.   </mx:HBox>
  11. </mx:ViewStack>

Example 3 - A exemplo simples de ViewStack
Inicialmente, o valor de selectedIndex é 0. Com esta configuração “box1″ seria visível. Se você emitir o seguinte comando

Actionscript:

  1. myViewStack.selectedIndex = 1;

Example 4 - Configurando o selectedIndex
Então a caixa denominada “box2″ seria visível. No entanto, se você aplicar o ModelLocator a este conceito, você poderia usar o workflowState varaible para definir a propriedade selectedIndex. Ao vincular a selectedIndex ao valor workflowState, agora você tem controle total sobre o que é apresentado no ViewStack de seu ModelLocator

mxml:

  1. <mx:ViewStack id=”myViewStack” selectedIndex=”{modelLocator.workflowState}”>
  2.   …
  3. </mx:ViewStack>

Example 5 - vinculando o selectedIndex ao workflowState

Definir constantes para melhorar o código

Seria simples para manipular a view utilizando este método, porém, poderia levar o código potencialmente confuso. Por exemplo, suponha que você tem os seguintes:

• Um ViewStack com dois filhos: um login e uma tela Welcome
• O ViewStack’s selectedIndex está vinculado à propriedade workflowState
• Um botão login que executa a ação mostrada no Exemplo 4.

Isto pode parecer como se ele funcionasse corretamente, mas ele não conta para quaisquer alterações. Se outro filho é adicionado à ViewStack, poderia ficar fora da ordem. Tem de haver uma maneira melhor para definir manualmente a propriedade selectedIndex. Para conseguir isso, você só precisa definir constantes dentro da ModelLocator

Actionscript:

  1. //DEFINE YOUR VARIABLES HERE
  2. public var workflowState:uint = 0;
  3. // DEFINE VIEW CONSTANTS
  4. public static const LOGIN_SCREEN = 0;
  5. public static const WELCOME_SCREEN = 1;

Example 6 – Definindo constantes View no ModelLocator.

Ao usar esse método, você só tem que alterar o valor em um único local, se o número de children ou a ordem das children mudarem no ViewStack. Agora, você deve atribuir o botão login as seguintes medidas para o evento clique.

Actionscript:

  1. myViewStack.selectedIndex = ViewModelLocator.WELCOME_SCREEN;

Example 7 – Fixando a View com constantes definidas.

Não só para proteger contra futuras mudanças, você também fez o seu código muito mais lógico. Outro desenvolvedor poderia facilmente analisar o código e entender o processo sem ter de referenciar todas as children no ViewStack.

Tradução do original inglês: http://www.davidtucker.net

Iniciando com Cairngorm – Parte 1

Flex / Cairngorm 2 Comments »

Falei sobre Cairngorm 2,2 no Flex Max Bootcamp no decurso desta semana. Muitas pessoas estavam interessadas em Cairngorm, mas eu tinha apenas cerca de 10 minutos para explicar os conceitos básicos de Cairngorm. Eu acho que a maneira mais fácil de ajudar estas pessoas é fazer uma rápida série sobre os benefícios de Cairngorm no meu blog. Esta série irá combinar artigos com “code-along” vídeos.

Aviso: Não afirmo ser um “expert” na Cairngorm - estou longe disso. No entanto, tenho usado Cairngorm em vários grandes projetos (tanto no Georgia Tech e no meu próprio negócio). Estou certamente aberto a correções, caso você veja que cometi algum erro neste projeto. Se você quiser que “os peritos” check out: Steven Webster, Alistair McLeod, Alex Uhlmann, e Peter Martin.

Nota: Os rapazes no Adobe Consulting (que desenvolveu Cairngorm) estão investigando algumas coisas novas com o quadro como um todo. É possível (na verdade provável), que algumas dessas coisas vão mudar no futuro. Uma das áreas muito específicas da mudança é o Model Locator.

Parte 1 – Usando um Model Locator

O Model Locator pattern é utilizado em Cairngorm, mas você não tem que ter uma plena implementação do Cairngorm para usar o pattern. Primeiro, vamos cobrir aquilo que você recebe de benefícios ao utilizar um modelo Locator.

Um Modelo Locator é um repositório centralizado de todos os dados que é necessário em toda a sua aplicação. Seus dados irão existir dentro de uma “Classe Singleton”. Esta “classe” pode ter apenas um exemplo de si mesmo. Por que isso é importante? Deixe-me dar-lhe um exemplo.

Temos grandes mini-notepads no trabalho que eu uso para anotar dados enquanto eu trabalho. No entanto, por vezes, eu perco um bloco - obtenho um novo e, em seguida, localizo o antigo. Depois de tanto ter sido largamente utilizados - é realmente difícil descobrir qual bloco eu estava usado para anotar um pedaço de informação de uma semana atrás. Esse é um exemplo simples - mas imagina se eu tivesse 20 blocos? Isto poderia deixar vocês loucos.

Da mesma forma, você poderá ter uma “classe” que recebe “instanciado” 20 vezes dentro de sua aplicação (mesmo que você não quer dizer para ela o que fazer). A maneira mais fácil de eliminar este problema é usar um único “Singleton”. Um singleton é uma classe que nunca é “criada” na forma tradicional. Tem uma regra principal - não mais que um por si só pode existir, em qualquer momento. Como ele faz isso? Eu mostrarei no exemplo Model Locator.

Actionscript:

  1. package net.davidtucker.CairngormSample.model {
  2.     import com.adobe.cairngorm.model.IModelLocator;
  3.    
  4.     [Bindable]
  5.     public class ModelLocator implements IModelLocator {
  6.        
  7.         // Single Instance of Our ModelLocator
  8.         private static var instance:ModelLocator;
  9.         public function ModelLocator(enforcer:SingletonEnforcer) {
  10.         if (enforcer == null) {
  11.                 throw new Error( “You Can Only Have One ModelLocator” );
  12.             }
  13.         }
  14.         
  15.         // Returns the Single Instance
  16.         public static function getInstance() : ModelLocator {
  17.                
  18.             if (instance == null) {
  19.                 instance = new ModelLocator( new SingletonEnforcer );
  20.             }
  21.             return instance;
  22.         }
  23.        
  24.         //DEFINE YOUR VARIABLES HERE       
  25.        
  26.     }
  27. }

// Classe Utilitária para negar o acesso ao construtor

  1. class SingletonEnforcer {}

Este código pode parecer um pouco assustador no início, mas confiem em mim que não é tão difícil como pode parecer. Em primeiro lugar, temos o nosso pacote definição e nós importamos algumas classes. Neste momento sabemos que teremos o IModelLocator interface. Para utilizá-lo vai precisar do Cairngorm SWC que pode ser encontrado aqui: http://labs.adobe.com/wiki/index.php/Cairngorm:Cairngorm2.2:Download. Além disso, note - você pode construir um model Locator sem Cairngorm, e faço isso com freqüência em pequenos projectos (você acabou de deixar de fora os códigos “implements IModelLocator” e “import com.adobe.cairngorm.model.IModelLocator “ do Model Locator).

Actionscript:

  1. [Bindable]
  2. public class ModelLocator implements IModelLocator {
  3.        
  4.      // Single Instance of Our ModelLocator
  5.      private static var instance:ModelLocator;

Em seguida, temos a nossa definição da classe. É importante que você use o Bindable metatag diretamente acima de sua classe. Isso permitirá que todas as nossas variáveis que definimos dentro do Modelo Locator serão utilizadas para vinculação. Também irá avançar e criar uma variável. Ela será chamada de “instance” e será do tipo ModelLocator. Esta será a variável onde vamos guardar as instâncias das classes. Também será denotado como uma propriedade “static”. Se você não tem certeza o que é uma propriedade “static”, ok - vamos discutir na nossa próxima lição.

Actionscript:

  1. public function ModelLocator(enforcer:SingletonEnforcer) {
  2.      if (enforcer == null) {
  3.           throw new Error( “You Can Only Have One ModelLocator” );
  4.      }
  5. }

Este é seguido pelo construtor. O construtor assume argumento - “enforcer”. Você irá notar que esta “enforcer” tem um tipo “SingletonEnforcer”, que é definido logo após a nossa classe. Segue-se a lógica de que:

• Quando você coloca uma classe em um arquivo Actionscript abaixo da classe principal, ela só está disponível para essa classe. Muitas pessoas referem-se a estes como “utility classes” (embora muitas pessoas usam esse termo com um alcance muito mais amplo).
• Se o construtor exige este argumento - só então a nossa classe principal pode criar uma instância de si mesmo, porque não temos acesso a classe “SingletonEnforcer” - só a principal classe tem esse acesso.
• Não iremos acessar a nossa classe na forma normal, usando a declaração “new”, porque não se pode chamar o construtor (vou mostrar-lhe como vamos fazê-lo em um bit).

Assim que chegar dentro do construtor, temos algumas linhas certifique-se de que as coisas funcionem como planejadas. A declaração “if” garante que passamos um “enforcer” válido. Se não, haverá um Erro “Você Pode Ter Apenas Um ModelLocator”.

Actionscript:

  1. // Returns the Single Instance
  2. public static function getInstance() : ModelLocator {
  3.      if (instance == null) {
  4.           instance = new ModelLocator( new SingletonEnforcer );
  5.      }
  6.      return instance;
  7. }

A função “getInstance” é a forma como iremos acessar nosso ModelLocator do nosso pedido. Esta função apenas passa para trás o “exemplo” da classe. Se ela ainda não existe, ele irá criá-la. Podemos agora começar um ModelLocator usando o código a seguir

Actionscript:

var model:ModelLocator = ModelLocator.getInstance();

Tradução do original inglês: http://www.davidtucker.net