Camada de Visualização (Commons UI)
Conforme citado na seção de contextualização, a arquitetura proposta visa eliminar os problemas identificados em diversos projetos já executados, onde foi possível identificar a falta de padronização para realizar tarefas comuns no processo de desenvolvimento. Assim, temos como objetivo principal desta seção o detalhamento do projeto Commons UI que provê soluções para que seja possível estabilizar, o que era previamente uma atividade caótica, em uma atividade produtiva e padronizada. Em busca deste equilíbrio, foram estudadas soluções e padrões de mercado que balizam o desenvolvimento de software atualmente.
O framework AngularJS foi a opção escolhida após compararmos as soluções disponíveis. A possibilidade de extensão do framework nos proporciona a flexibilidade necessária para criar componentes personalizáveis que atendem plenamente as nossas necessidades. Além do benefício da extensibilidade, o framework possui uma documentação detalhada, comunidade participativa e componentes genéricos já desenvolvidos e inclusos na solução. Para maiores detalhes, consulte o guia para desenvolvedores do AngularJS.
Esta seção será dividida em três grandes tópicos: estrutura, detalhamento da estrutura e melhorias futuras. O primeiro tópico aborda a organização do projeto e responsabilidade de cada componente, descrevendo breviamente o comportamento dos componentes que compõem a estrutura do projeto. O tópico de detalhamento mostra detalhadamente o funcionamento dos componentes, a comunicação entre diferentes componentes e sua utilização pelo desenvolvedor. E por fim, o tópico de melhorias, no qual irá listar diversas melhorias que podem ser realizadas pela equipe de arquitetura para facilitar na construção de novos componentes e manter a atual estrutura da arquitetura estável.
O diagrama abaixo ilustra, de forma macro, a comunicação e organização dos componentes na atual versão da arquitetura.
- Componentes disponibilizados pelo AngularJS com uma API que nos possibilita registrar services, factories e providers para compartilhar código de uso comum, reduzir a repetição de código e padronizar regras de negócio.
- Diretictive customizada que é responsável pela internacionalização. Esta directive utiliza APIs públicas de diferentes serviços e se comunica com outras directives através de eventos.
- Área onde o desenvolvedor irá trabalhar. Nesta área o desenvolvedor tem acesso a partials, scopes e directives para criar telas CRUD. Esta área interage com componentes customizados através de injeção de dependência e uso de directives em partials. Para maiores informações, leia as seções O que é um Partial?, O que é um Controller? e O que é Scope?.
O que é um Service?
São objetos que compartilham código através de APIs públicas para toda aplicação que faz uso do AngularJS. Services fornecem injeção de dependência e padronização quanto a criação de APIs públicas.
Services são registrados a partir da Module API. Ao registrar um service, dá-se um nome no qual será utilizado para injeção de dependências em quaisquers outros componentes do AngularJS. Abaixo temos um exemplo de como registrar um service e como utiliza-lo através da injeção de dependências.
Note a forma que declaramos a função foo no service acima. Internamente, ao declarar um service, a função retornada será instanciada apenas quando necessário (lazy). Esta instanciação dá-se chamando construtor da função através do operador new.
O que é um Factory?
Assim como o service, factories também são objetos que compartilham interfaces públicas de API e são passíveis a injeção de dependências.
Factories são registradas através da Module API . Ao registrar uma factory, dá-se um nome no qual será utilizado para injeção de dependências em quaisquers outros componentes do AngularJS. Abaixo temos um exemplo de como registrar uma factory e como utiliza-la através da injeção de dependências.
Note a forma que declaramos a função foo na factory acima. Internamente, ao declarar uma factory, a função foo já esta instanciada e apenas será executada, diferentemente do service onde uma nova função será instanciada através do operador new.
O que é um Provider?
O que é uma Directive?
O que é um Partial?
O que é um Controller?
O que é Scope?
Estrutura
Conforme a imagem abaixo, o projeto é estruturado por pastas, cada qual refletindo a responsabilidade de seus componentes. Como este projeto é inteiramente composto de arquivos Javascript, não existem dependencias de outros projetos.
| Pasta | Descrição |
|---|---|
| Directives | Contém todas as diretivas customizadas que estão disponíveis para uso dos desenvolvedores. Estas diretivas foram criadas para atender os requisitos da arquitetura e não interferem nas diretivas do AngularJS. |
| Filters | Contém filtros customizados que estão disponíveis para uso dos desenvolvedores. Estes filtros foram criadas para atender os requisitos da arquitetura e não interferem nas diretivas do AngularJS. |
| Lang | Contém funções utilitárias, não disponibilizadas pela API Javascript nativa dos navegadores. Podemos citar como exemplo as funções: each e curry. |
| Providers | Contém providers utilizados internamente pela arquitetura para evitar alto acoplamento entre as diretivas. |
| Services | Contém serviços declarados através da API do AngularJS que estão disponíveis para injeção e podem ser utilizados pelos desenvolvedores para padronizar e agilizar o processo de desenvolvimento de novas funcionalidades. |
| Style | Contém arquivos .css para padronização de elementos de UI. |
| Vendor | Contém as bibliotecas previamente citadas neste documento já minificadas. |
Além das pastas que agrupam os componentes por responsabilidade, o projeto possui o arquivo treelayer-bootstrap que provê um módulo onde estão listadas todas as dependencias. Este arquivo existe para que quando necessário, projetos especifiquem como dependência apenas este módulo e todos os componentes estarão automaticamente associados ao projeto.
Providers
Providers são objetos expostos para toda a aplicação, passíveis de injeção, oferecem funções públicas e podem ser utilizados dentro de um bloco de configuração do AngularJS. Para maiores informações leia a documentação oficial sobre providers.
Message Provider
É o componente responsável por disponibilizar mensagens, descrições e validações e controlar o fluxo de execução das diretivas que fazem uso destes itens. Este componente é apoiado por endpoints RESTful que fornecem estas informações de forma dinâmica. Para realizar estas chamadas, em um bloco de configuração do AngularJS é possível configurar as diferentes URLs através de injeção de dependências. Abaixo temos uma imagem do projeto Shield, onde é configurado as URLs utilizadas pelo MessageProvider.
As funções disponíveis publicamente são:
| Nome | Descrição | Utilização |
|---|---|---|
whenMessageLoads | Fornece uma forma de se registrar a este provider e, quando o back-end retornar, o provider irá alertar os componentes registrados. | |
getRawMessages | Retorna um objeto contendo todas as mensagens, validações e descrições. Este objeto não sofreu nenhuma modificação por directives, esta no formato raw. | |
getValidations | Retorna um objeto contendo todas as validações. | |
createReference | Usado principalmente pela directive tl-ref, na qual cria o cache de referências. Este método é público mas não deve ser utilizado, foi criado para estabelecer a comunicação entre a directive e o cache de referências. | |
findMessagesByKey | Busca uma determinada mensagem pela chave contida no arquivo property. |
Busca de Mensagens
A partir de uma chamada da principal directive, tl-object, é disparada uma requisitção HTTP para um método genérico da arquitetura para buscar mensagens internacionalizadas. Esta funcionalidade baseia-se no nome do objeto passado para a directive tl-object para buscar as mensagens. Mensagens são compostas de labels, descriptions, validations, etc.
As URLs previamente configuradas ao inicializar um aplicação AngularJS servem como endpoint para esta funcionalidade.
Armazenamento de Mensagens
Após a resposta do servidor, se ocorrida com sucesso, todas as mensagens são armazenadas em cache no formato raw, ou seja, sem alteração nenhuma. Assim que possível outras diretivas irão processar estas mensagens e preencher outras áreas de cache deste provider.
Controle de Fluxo
Logo após a busca de mensagens e a resposta do servidor, todas as diretivas que se registraram neste provider serão avisadas que há mensagens não processadas. A directive tl-ref iniciará sua execução preenchendo o cache referenceMessages a com uma nova estrutura, oriunda do cache no formato raw. Este cache é disponibilizado para outras diferitvas através da função pública exposta findMessagesByKey.
Se você possui dúvidas quanto a funcionalidade das directives citadas nesta seção, leia as seções de directives Object e Ref.
Services
Services são objetos compostos primariamente por funções, passíveis de injeção de dependências e não possuem estado. Um serviço no framework AngularJS é tratado como um singleton e pode ser injetado através de seu nome, bastando declara-lo como parametro em seus componentes (no caso, um controller, por exemplo). Para maiores informações acesse a documentação oficial sobre services.
Dialog Service
É um serviço declarado através do framework AngularJS que possui unicamente a funcionalidade de retornar um objeto que controla estados de um dialog. Mencionamos na introdução de services que estes não possuem estado, porém o que citamos na anteriormente foi que o Dialog Service tem como unica funcionalidade retornar um objeto com estados. Como isto se dá? Basicamente este serviço possui uma única função, a função responsável por criar o objeto dialog, ou seja, o Dialog Service não possui estado, mas sim objeto obtido no retorno desta chamada.
As funções disponíveis publicamente são:
| Nome | Descrição | Utilização |
|---|---|---|
new | Cria um objeto do tipo Dialog para que o usuário possa controlar as operações e a visibilidade de um determinado dialog. |
|
Dialog
Dialog é um objeto definido internamente no service DialogService e tem como responsabilidade controlar os estados de um dialog. O estado é basicamente quando o dialog está aberto e a operação que esta ocorrendo no momento. Para obter um objeto do tipo Dialog basta realizarmos uma chamada para a função new no DialogService.
Property Service
É um serviço declarado através do framework AngularJS que expõe funções públicas para trabalhar com propriedades, encapsulando a complexidade de realizar requisições HTTP para o desenvolvedor. Para maiores informações, leia a documentação de resources.
As funções disponíveis publicamente são:
| Nome | Descrição | Utilização |
|---|---|---|
properties | A partir do nome de objeto, busca todas as propriedades deste objeto no back-end. | |
range | A partir de um objeto e um atributo, busca a série se existente no arquivo de internacionalização. |
|
Submit Service
É um serviço declarado através do framework AngularJS que expõe funções públicas para trabalhar com propriedades, encapsulando a complexidade de realizar requisições HTTP para o desenvolvedor. Para maiores informações, leia a documentação de resources.
As funções disponíveis publicamente são:
| Nome | Descrição | Utilização |
|---|---|---|
| properties | A partir do nome de objeto, busca todas as propriedades deste objeto no back-end. | |
| range | A partir de um objeto e um atributo, busca a série se existente no arquivo de internacionalização. |
|
Directives
Nesta seção abordaremos como cada directive disponível na arquitetura funciona internamente.











