sexta-feira, 22 de março de 2019

Pegando o RealPath em uma aplicação JEE


As vezes precisamos do RealPath da nossa aplicação para lermos e/ou escrevermos arquivos através do Java, e em aplicações JavaEE uma boa forma de fazermos isso é através de um ServletContextListener, uma vez que este listener escuta quando sua aplicação inicializa ou finaliza no container web ou servidor de aplicação.

Usando o ServletContextListener ao invés do FacesContext para pegar o RealPath não ficamos presos ao JSF por exemplo, ou outra tecnologia, e podemos usar o RealPath em processos e situações diversas.

Geralmente tenho uma classe em um pacore br.com.meudominio.utils chamada Constants onde guardo algumas constantes e variáveis estáticas com algumas configurações do sistema (embora prefira usar um cadastro de Parâmetros Gerais do Sistema para a maioria das configurações), e ao pegar o RealPath é nessa classe que seto essa configuração. Veja o código do listener abaixo:

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebFilter;

import br.com.meudominio.Constants;

@WebListener
public class RealPath implements ServletContextListener{

    @Override
    public void contextDestroyed( ServletContextEvent sce ) {
        Constants.REAL_PATH = sce.getServletContext().getRealPath( "/" );
       
    }

    @Override
    public void contextInitialized( ServletContextEvent sce ) {
        // TODO Auto-generated method stub
       
    }

}

Na classe Constants tenho algo como:

public final class Constants
{
      ...

public static String REAL_PATH = "";

     ...
}

Pronto, em qualquer lugar do sistema basta usar Constants.REAL_PATH para pegar o RealPath da minha aplicação.

terça-feira, 19 de março de 2019

Criando uma biblioteca de componentes com Angular 7, utilizando em projetos externos e publicando no NPM


Frameworks JavaScript estão sempre mudando, e geralmente são mudanças complexas que nos obrigam a reaprender como fazemos as coisas. Não foi diferente com a questão da criação de bibliotecas do Angular, que até a versão 5 era apenas um projeto comum, o qual empacotávamos no formato NPM e publicávamos. Agora, a partir da versão 7 em diante o Angular cria uma espécie de workspace, onde é possível criar vários projetos e bibliotecas, e são essas bibliotecas internas que podemos exportar e podemos usar em outros projetos, e até publicar no NPM.

Com isso, muita coisa mudou, porque essa biblioteca interna, (pelo menos por enquanto, até a versão 7.1.2 do Angular), não contém os arquivos environments.prod.ts e environments.ts para tratarmos a diferença entre algumas configurações de produção e o ambiente de desenvolvimento, também não existe a estrutura da pasta assets para colocarmos nossas imagens e o Angular conseguir encontrá-las de forma fácil.

Essas dificuldades eu contornei da seguinte forma: as imagens eu coloco em texto base64 direto na tag <img> e quando preciso pegar uma URL em uma biblioteca uso JavaScript para obter a URL de forma dinâmica: (window.location.protocol + window.location.hostname;).

Outra mudança que houve foi o arquivo angular-cli.json que teve seu nome alterado para angular.json e sua estrutura mudou um pouco, passando a conter múltiplos projetos (como o de testes e as bibliotecas) pois como disse, o que criamos com “ng new” a partir da versão 7 do Angular se comporta como um workspace.

Agora que já falamos das mudanças e alguns contratempos que tive com elas, vamos a criação do projeto. Abrindo no terminal a pasta do seu workspace, digite:

$        ng new teste --create-application=false

          Quando indagado sobre a criação do Router e do CSS escolha as opções padrão.

A opção --create-aplication usada acima também é nova, e faz com que o Angular não crie o projeto inicial, bem com a pasta src, criando apenas o Workspace Angular por assim dizer. Basicamente isso é útil para criarmos bibliotecas, pois gera um workspace de mesmo nome da biblioteca. Note que o Angular aceita tanto comandos com camelCase quanto separados por ífem (-), então poderia ser --createApplication=false.

          Aproveite e dê uma olhada nos arquivos package.json que continua com as dependências do projeto  e angular.json, que está praticamente vazio aguardando a criação de um projeto ou biblioteca.

          Vamos criar a biblioteca, posicione o terminal na nova pasta criada (teste):

$        cd ..

E crie a biblioteca com o seguinte comando:

$        ng g library teste --prefix=lib

          Na linha acima, foi criada a biblioteca “teste” e ao invés de usarmos o prefixo “app” como de costume, dissemos para o Angular usar o prefixo “lib”. Fique à vontade para escolher o prefixo que desejar, isso é importante para evitar conflitos entre a biblioteca e os apps que a usam.
         
          Note que o conteúdo do arquivo angular.json mudou, temos nele a propriedade que indica a versão do projeto: “version”, a propriedade que indica o pacote raiz que contém os projetos: “newProjectRoot”, e então temos a propriedade que indica os nossos projetos: “projects”. Dentro da propriedade “projects” há uma propriedade para cada projeto que criarmos, nesse caso haverá apenas o projeto “teste”, e dentro da propriedade “teste” teremos as propriedades de configuração deste projeto específico, como o tipo do projeto, o prefixo usado, a raiz do projeto, o source do projeto e outras configurações pertinentes.

A estrutura do projeto também foi alterada, agora existe uma pasta “projects” com a pasta “teste” que é o nosso projeto dentro dela; e dentro da pasta “teste” temos o diretório “src” que conterá tudo que pertencer a lib propriamente dita, o arquivo “package.json” da lib que especificará suas dependências que serão compiladas e posteriormente instaladas junto com ela quando um cliente usar npm install e também o arquivo ng-package.json. Os demais arquivos são de menor importância. É também no arquivo “package.json” da lib que especificamos o autor, a licença, o repositório, etc.

       A lib já foi criada contendo um componente e um service dentro de src/lib . Também vemos outro arquivo importante dentro da pasta src: public_api.ts. Nesse arquivo devemos exportar todos os módulos, componentes e services que criarmos, para que possam ser usados por quem instalar nossa biblioteca.

          export * from './lib/teste.service';
export * from './lib/teste.component';
export * from './lib/teste.module';

No diretório principal, o arquivo “tsconfig.json” tem as configurações de transpilação e build do projeto. Ele recebe o path da biblioteca que criamos para podermos usar nesse projeto, enquanto que em projetos externos ela será instalada com npm install e o conteúdo ficará em node_modules.

"paths": {
      "teste": [
        "dist/teste"
      ],
      "teste/*": [
        "dist/teste/*"
      ]
}

          Vamos buildar o projeto:

$        ng build teste   

          Veja que o projeto é buildado normalmente. Mas a frente vamos ver como usá-lo em outro projeto e também como publicar no npm. Agora vamos ver como criar novos componentes para a biblioteca. Digite o comando abaixo:

$        ng g c meu-componente --project=teste

Veja que a única coisa que mudou foi que especificamos em qual projeto o componente seria gerado pelo AngularCli. O novo componente deve ser declarado no módulo da nossa biblioteca e também no arquivo de entrada, o public_api.ts.

Com isso podemos re-buildar nossa aplicação. Uma novidade desde a versão 6.2 é o re-build pode ser automático a medida que arquivos forem alterados, para isso basta acrescentar a opção --watch no momento do build, a partir de então os demais serão disparados sozinhos.

$        ng build teste --watch

Agora vamos ver como usar a biblioteca em um projeto externo e como publicar no npm.

Para isso temos que empacotar nossa biblioteca em uma arquivo .tgz, por tanto, vamos criar um script no “package.json” raiz para facilitar este trabalho. Na seção “scripts” adicione o seguinte trecho de código:

"scripts": {
    ...
    "npm_pack_teste": "cd dist/teste && npm pack"
 }

Agora podemos usar o seguinte comando para empacotar a biblioteca “teste”:

$        npm run npm_pack_teste

Isto criou o arquivo “teste-0.0.1.tgz” dentro de “dist/teste” com a versão especificada no arquivo “package.json” da lib como já dito anteriormente. Podemos inclusive criar um script que faz o build e o empacotamento de uma só vez:

"scripts": {
    ...
    "npm_pack_teste": "cd dist/teste && npm pack",
    "package_teste": "ng build teste && npm run npm_pack_teste "
 }

E agora basta executar:

$        npm run package_teste

Pronto, temos nossa biblioteca buildada e empacotada para usarmos onde quisermos! Para usarmos em projetos próprios não precisamos publicar no npm. Isso é bom para empresas que não querem expor suas bibliotecas, pode-se criar um repositório interno para elas e quando for usar o npm install basta passar o caminho completo de onde a biblioteca está.

Uma vez instalada a biblioteca, o uso é normal como qualquer pacote npm instalado na aplicação.

Agora vamos a publicação no npm. Antes de criar uma biblioteca, se é sua intenção publicá-la no npm é bom checar se o nome que pretende dar a sua biblioteca já não existe lá, para evitar ter que mudar depois de criado todo o projeto.

O arquivo “package.json” deve estar com as informações de nome, versão, autor, licença, repositório, palavras chaves e outras além das dependências, scripts, etc... como abaixo:

...
"name": "teste",
"version": "1.0.0",
"license": "MIT",
"author": {
    "name": "seu_nome",
    "email": "seu_email",
    "url": "seu_site_ou_blog"
 },
 "bugs": {
 "url":"url_issues_git"
  },
 "homepage":"url_git",
 "keywords": [
    "angular",
    "angular2",
    "angular4",
    "p-calendar",
    "p-calendar-ptbr",
    "primeNG",
    "datepicker",
    "calendar",
    "pt-BR"
 ],
 "repository": {
    "type": "git",
    "url": "git+https://endereço_rep_git"
 },
...

O npm usará sua página de README.md com a página inicial da sua biblioteca no servidor. Como agora estamos tratando de mais de uma biblioteca por workspace, o README.md deve ser copiado para o destino onde a biblioteca é buildada. Caso haja um arquivo LICENSE também deve ser colocado lá.

É preciso criar uma conta caso você não tenha, ou fazer login para poder compartilhar seus pacotes. A criação da conta é bem simples e eles pedem um username, password e e-mail. É necessário a confirmação do e-mail antes de publicar algo caso a conta seja nova. O comando para criar uma conta é:

$       npm adduser

Ao criar a conta ele já loga no NPM. Para efetuar logins posteriores, os mesmos dados são pedidos, e o comando é:

$       npm login

Agora podemos publicar nossa biblioteca, digitando o comando npm publish e passando o caminho do arquivo .tgz gerado:

$        npm publish .\dist\teste\teste-0.0.1.tgz

Bom, o artigo ficou um pouco grande porque expliquei algumas coisas com detalhes, mas espero ter ajudado! Abraços!




Links de referência:









sábado, 1 de dezembro de 2018

Resumo sobre COBIT

Para estudar para provas e concursos. Sempre cai algo sobre Governança de TI, COBIT, ITIL, PMBOK, Scrum e XP, então resolvi fazer resumos rápidos sobre cada um destes assuntos, e o blog é um lugar de manter acesso fácil e rápido :) .

COBIT => Control Objectives for Information and Related Technology/Objetivos de Controle para a Informação e Tecnologia.

É um guia de gerenciamento de TI que indica e descreve boas práticas voltadas à gestão de TI. De forma breve, o conteúdo do COBIT® aborda o gerenciamento do negócio por meio de controles para a área de TI.

É um manual composto de princípios, regras e indicadores de controle que compõem um modelo de gestão de TI.

É uma metodologia que estabelece um modelo de controle para Governança de TI.

Evolução

Auditoria => Controle de resultados e objetivos => Gestão (Abrange ITIL e PMBOK) => Governança de TI (Avaliar, Dirigir e Acompanhar) => Governança corporativa de TI
Cada um corresponde a uma versão do COBIT (1,2,3,4 e 5)

As práticas do COBIT® são fortemente focadas mais nos controles e menos na execução: otimizar os investimentos em TI, assegurar a entrega dos serviços e prover métricas para julgar quando as coisas saem erradas.

É possível que o COBIT® NÃO ajude diretamente no cotidiano do profissional de TI. No entanto, certamente, o COBIT® contribui para que a empresa alcance o alinhamento estratégico da TI, independentemente de seu setor de atuação.

O principal objetivo do COBIT® é ser orientado ao negócio, ou seja, voltado para fazer com que a área de TI trabalhe de forma a possibilitar que os produtos/serviços da empresa sejam realizados de forma eficiente.

O COBIT® oferece diretrizes de fácil compreensão para que esses executivos possam tomar decisões sobre a TI.

O COBIT® oferece um conjunto de processos bem estruturados de TI que permite à empresa disponibilizar serviços que garantam a PRODUÇÃO DE INFORMAÇÕES VITAIS para a tomada de decisão e, consequentemente, para a definição dos requisitos de negócio (efetividade, eficiência,confidencialidade, integridade, disponibilidade, conformidade, confiabilidade).

A INFORMAÇÃO é foco do papel fundamental do COBIT®, porque seu perfeito gerenciamento é a parte central de qualquer sistema de Governança em TI, sendo fundamental, também, para alinhar os processos de TI à estratégia da empresa. É por meio do bom gerenciamento da informação que a tomada de decisões e a definição de requisitos de negócios obtêm sucesso.

O COBIT® divide a atuação da TI em quatro domínios, 34 áreas de processos e 210 atividades, com o objetivo de promover a melhoria contínua das organizações. Mas de que forma ocorre essa melhoria contínua?
Os quatro domínios do COBIT® estão relacionados às quatro etapas do ciclo PDCA:
Planejar e Organizar (PO) ➞ Plan
Adquirir e Implementar (AI) ➞ Do
Entregar e Suportar (DS) ➞ Check
Monitorar e Avaliar (ME) ➞ Act

As 34 áreas de processos estão divididas entre os quatro domínios. Esses domínios, direta ou indiretamente, obedecem à mesma filosofia de melhora contínua do ciclo PDCA. Isso significa dizer que a TI deve buscar a melhora contínua de cada um dos 210 processos.

Como os domínios se dividem em processos no COBIT®?

Planejar e Organizar:
PO1: Definir um plano estratégico de TI
PO2: Definir a arquitetura da informação
PO3: Determinar o direcionamento tecnológico
PO4: Definir os processos, a organização e os relacionamentos da TI
PO5: Gerenciar o investimento de TI
PO6: Comunicar as diretrizes e expectativas da diretoria
PO7: Gerenciar os recursos humanos de TI
PO8: Gerenciar a qualidade
PO9: Avaliar e gerenciar os riscos de TI
PO10: Gerenciar projetos

Adquirir e Implementar
AI1: Identificar soluções automatizadas
AI2: Adquirir e manter software aplicativo
AI3: Adquirir e manter infraestrutura de tecnologia
AI4: Habilitar operação e uso
AI5: Adquirir recursos de TI
AI6: Gerenciar mudanças
AI7: Instalar e homologar soluções e mudanças

Entregar e Suportar
DS1: Definir e gerenciar níveis de serviço
DS2: Gerenciar serviços de terceiros
DS3: Gerenciar capacidade e desempenho
DS4: Assegurar continuidade de serviços
DS5: Assegurar a segurança dos serviços
DS6: Identificar e alocar custos
DS7: Educar e treinar os usuários
DS8: Gerenciar a central de serviço e os incidentes
DS9: Gerenciar a configuração
DS10: Gerenciar os problemas
DS11: Gerenciar os dados
DS12: Gerenciar ambiente físico
DS13: Gerenciar as operações

Monitorar e Avaliar
ME1: Monitorar e avaliar o desempenho
ME2: Monitorar e avaliar os controles internos
ME3: Assegurar a conformidade com requisitos externos
ME4: Prover a governança em TI

Recursos de TI: Aplicativos, Informação, Infraestrutura e Pessoas.

Compreendemos como infraestrutura tecnológica todos hardwares, todos equipamentos de redes, todas mídias e todos softwares, todos sistemas operacionais e de gerenciamento de banco de dados, além do próprio ambiente que suporta essa infraestrutura.

O COBIT® e a Governança de TI

Um dos conceitos chaves do COBIT é o das 5 áreas de foco de Governança: Alinhamento Estratégico, Entrega de Valor, Gestão de Recursos, Gestão de Riscos e Mensuração de Desempenho.

O COBIT® assumiu do COSO os três princípios da Governança, que são: responsabilidade, prestação de contas e transparência.

Surge uma preocupação importante em todas as áreas de processo: a de determinar os papéis e as responsabilidades dos envolvidos, ou seja, o que cada membro da equipe deve fazer para que os serviços da TI sejam realizados com eficiência e da melhor forma possível.

A Matriz RACI é uma ferramenta simples de gestão e serve para gerir atividades estabelecidas:
R = Responsável = Quem faz
A = Aprovador = Chefe imediato
C = Consultor = Quem tem conhecimento para ajudar
I = Informado = Autoridade a ser informada (grupo de pessoas a ficar por dentro das atividades)



Conteúdo baseado no curso gratuíto da Escola virtual do Bradesco: https://www.ev.org.br/

Resumo sobre Angular 4

Como estamos sempre lidando com muitas tecnologias diferentes, cada uma delas cheia de particularidades, as vezes faço um resumo para não perder muito tempo procurando o básico. Esse é meu resumo pessoal sobre o Angular 4.

NPM

- npm install nome_da_biblioteca --save
- npm uninstall nome_da_biblioteca --save

Angular-Cli

- ng new nome_do_projeto => cria um projeto,  inclusive a pasta raiz.
- ng init => quando já existir a pasta raiz e quiser criar a estrutura do projeto (deve ser executado no diretório).
- ng serve => executa o projeto.
- ng g c nome-do-componente => cria o componente.
- ng g d nome-da-diretiva => cria uma diretiva.
- ng g s nome-do-servico => cria o serviço.
- ng g m nome-do-model => cria o módulo.
- ng g p nome-do-pipe => cria o pipe.
- ng lint => lista erros de javascript e anti-padrões do style guide do Angular

Componentes

- interpolação => {{variavel}}
- propert-binding => [propriedade]="variavel" => <input [value]="nome" />
- event-binding => (evento)="método" => (click)="salvar($event.target.value)"
- two-way-data-binding => [(ngModel)]="nome"
- comunicação do componente pai para o filho:

@Input() variavel: tipo;

- comunicação do componente filho para o pai:

@Output variavel_evento = new EventEmitter();

//em algum momento usa-se:
this.variavel_evento.emit(objeto_ou_valor);

Variável de referência

usa-se o '#' antes de um nome => #imputName => <input type="text" class="form-control" #imputName />
-então essa variável fica disponível em todo o template(componente.html), mas não no componente(componente.ts).
Para ser acessada no componente, tem duas formas:
-pode ser acessada através do decorator @ViewChild('nome_da_variavel')

@ViewChild('imputName') campo: ElementRef;
//para usar depois basta fazer:
//this.campo.nativeElement.value;

-pode ser passada para o componente através de um event:

<button type="button" class="btn btn-primary"
        (click)="adicionar(imputName.value)">Adicionar</button>
// valor será recebido no método adicionar(valor) do componente.ts.

Ciclo de vida:

- construtor
- ngOnChanges => disparado sempre quando o valor do property-binding é atualizado.
- ngOnInit => Quando o componente é inicializado.
- ngDoCheck => A cada ciclo de verificação de mudanças.
- ngAfterContentInit => depois de inserir conteúdo externo na view
- ngAfterContentChecked => a cada verificação de conteúdo inserido
- ngAfterViewInit => depois que o angular inicializa os componentes views e views filhas.
- ngAfterViewChecked => após a checagem dos componentes views e views filhas.
- ngOnDestroy => antes da destruição do componente.

Diretivas

- diretivas de componentes => diretivas dos nossos componentes => <meu-componente></meu-componente>
- diretivas estruturais => vem precedida de * (asterísco) => *ngFor, *ngIf, *ngSwitch, etc.
- diretivas de atributos => interagem com o elemento que doram aplicadas => ngStyle, ngClass, etc.
Ouvindo propriedades e eventos do hopedeiro da diretiva:
- @HostListener('evento')
- @HostBinding('propriedade')
- pode-se usar o @input() para receber valores de quem for usar o componente com a diretiva criada.
Exportar a diretiva:
- As diretivas podem ser exportadas e terem seus métodos expostos da seguinte forma:

@Directive({
  selector: '[nome_do_seletor_da_diretiva]',
  exportAs: 'nome_da_diretiva'
})

- Isso possibilita que sejam usados de outras formas, veja como pegar a diretiva e usar seus métodos:

<input type="text" class="form-control" [(ngModel)]="nome"
        (focus)="adicionado = false" nome_do_seletor_da_diretiva
        #campo="nome_da_diretiva">

<button class="btn btn-info" (click)="campo.metodo_da_diretiva()">Clique-me</button>


NG-CONTENT
- Permite passar conteúdo (incluindo outros componentes) para um componente.
- Se eu tiver um componente chamado exemplo-ng-content.component.html com o seguinte conteúdo:

<div class="panel panel-default">
  <div class="panel-heading">
    <ng-content select=".titulo"></ng-content>
  </div>
  <div class="panel-body">
    <ng-content select=".corpo"></ng-content>
  </div>
</div>

pode ser usado em outro componente desta forma:

<app-exemplo-ng-content>
    <div class="titulo">Título do Painel</div>
    <div class="corpo">
        Conteúdo passado para o componente.
    </div>
    <div class="corpo">
        Conteúdo passado para o componente 2.
    </div>
</app-exemplo-ng-content>

Form validations

- autocomplete="off" => desabilita autocomplite no formulário
- diretivas do angular:

required, email, minlength="5", maxlength="15", pattern="[a-zA-Z ]*"

- pegar o formulario:

<form #meuForm="ngForm">

- pegar campos do formulário:

<input type="text" #nome="ngModel" name="nome" [(ngModel)]="cliente.nome" />

- validar:

nome.haserror('required') => pode ser usado em um ngIf por exemplo e exibir ou não uma mensagem.

- propriedades interessantes:

nome_do_campo.touched => se o campo foi tocado
nome_do_campo.pristine => se o campo já teve algum valor ou está virgem
nome_do_campo.dirty => se o campo já foi alterado

- estilizando componentes invalidos dos forms com as classes do angular:

input.ng-invalid.ng-touched, select.ng-invalid.ng-touched {
  border: 1px solid red;
}

- binding de class:

<input type="text" #nome="ngModel" name="nome" [(ngModel)]="cliente.nome" [class.nome_da_classe]="propriedade_ou_condicao_boolean"/>

- binding de style:

<input type="text" #nome="ngModel" name="nome" [(ngModel)]="cliente.nome" [style.nome_da_propriedade]="propriedade_ou_condicao_boolean ? 'valor_1' : 'valor_2' "/>

- resetar um formulario:

<form autocomplete="off" #usuarioForm="ngForm"
      (ngSubmit)="salvar(usuarioForm)">

No submit do form estamos chamando o método salvar e passando o próprio form.
Então no componente basta resetarmos o form:

salvar(form: NgForm) {
//faz outras coisas
...
//reseta o formulário
    form.reset();
  }

Serviços

- A anotação @Injectable() permite que o serviço receba injeção de outros serviços.
- Serviços servem para comunicação com servidor.
- Para evitar duplicação de código.
- Lógica da aplicação deve estar nos serviços.
- Classes utilitárias devem ser feitas como serviços.
- Serviços são singletons se forem adicionados dentro de qualquer módulo na propriedade "providers: []" do decorator @NgModule. O que permite compartilhar recursos entre componentes naturalmente (listas, variáveis, etc).
- Caso sejam adicionados na propriedade "providers: []" do componente, serão uma instância para cada componente e
componentes filhos, o que já impede esse compartilhamento global.
- Uma vez criadas instâncias separadas por componentes, a comunicação entre eles só pode ser feita através do EventEmitter e se o EventEmitter for uma propriedade estática.

static variavel_evento = new EventEmitter();

//dentro de algum método
this.variavel_evento.emit( objeto_ou_valor );

- Quem for escutar o evento deve fazer da seguinte forma:

// no contrutor recebe o serviço
constructor(private cursosService: CursosService) {}

// no ngOnInit se inscreve como ouvinte
CursosService.criouNovoCurso.subscribe(
      //faz alguma coisa aqui
curso => this.cursos.push(curso)
    );

 - Os services são declarados no provider dos módulos ou componentes como já descrito acima,
da forma abreviada ou extensa.

Abreviada:

@NgModule({
  declarations: [
    AppComponent,
    FuncionarioCardComponent,
    FuncionarioFormComponent
  ],
  imports: [
    BrowserModule
  ],
  providers: [
    FuncionarioService
  ],
  bootstrap: [AppComponent]
})

Extensa

@NgModule({
  declarations: [
    AppComponent,
    FuncionarioCardComponent,
    FuncionarioFormComponent
  ],
  imports: [
    BrowserModule
  ],
  providers: [
    { provide: FuncionarioService, useClass: FuncionarioService, }
  ],
  bootstrap: [AppComponent]
})

Na forma extensa, é possível fornecer um método Factory ao invés de uma classe.
A vantagem é que a factory pode instanciar uma classe com parâmetros se for necessário.

const criarFuncionarioService = () => {
  return new FuncionarioAbreviadoService(param1, param2...);
}

@NgModule({
  declarations: [
    AppComponent,
    FuncionarioCardComponent,
    FuncionarioFormComponent
  ],
  imports: [
    BrowserModule
  ],
  providers: [
    { provide: FuncionarioService, useFactory: criarFuncionarioService }
  ],
  bootstrap: [AppComponent]
})

Rotas

- Cria-se uma constante em um arquivo app.routing.ts ou no app.module.ts que seja
do tipo Routes do pacote "@angular/router". Esse  paths e componentes.
- O Routes é um array de paths e componentes e deve ser preenchido como no
exemplo abaixo:

const  APP_ROUTES: Routes = [
  { path: 'lancamentos', component: LancamentosPesquisaComponent },
  { path: 'lancamentos/novo', component: LancamentosCadastroComponent },
  { path: 'pessoas', component: PessoasPesquisaComponent },
  { path: 'pessoas/novo', component: PessoasCadastroComponent }
]

- Essa constante deve passar para uma constante do tipo ModuleWithProviders do pacote "@angular/core".
- Para isso é preciso usar o RouterModule do "@angular/router". Se essa constante foi criada em um arquivo
separado, ela deve ser exportada. O código fica assim:

export const routing: ModuleWithProviders = RouterModule.forRoot(APP_ROUTES);

- Para usar as rotas coloca-se a diretiva routerLink nos links recebendo o devido path declarado na constante
que no exemplo chamei de APP_ROUTES.

<li class="navbar-menuitem"><a routerLink="lancamentos">Lançamentos</a></li>

- Para as rotas funcionarem, em cada módulo é necessário importar o RouterModule do '@angular/router'.

@NgModule({
  declarations: [
    AppComponent,
    ...
  ],
  imports: [
    BrowserModule,
    RouterModule
  ],
  providers: [
    ...
  ],
  bootstrap: [AppComponent]
})

- Para destacar rotas ativas, basta usar a diretiva routerLinkActive passando o nome da classe CSS que contém o estilo desejado.

<li class="navbar-menuitem" routerLinkActive="ativo"><a routerLink="lancamentos">Lançamentos</a></li>

Events

(focus)="myMethod()"  // An element has received focus
(blur)="myMethod()"   // An element has lost focus

(submit)="myMethod()"  // A submit button has been pressed

(change)="myMethod()"

(scroll)="myMethod()"

(cut)="myMethod()"
(copy)="myMethod()"
(paste)="myMethod()"

(keydown)="myMethod()"
(keypress)="myMethod()"
(keyup)="myMethod()"

(mouseenter)="myMethod()"
(mousedown)="myMethod()"
(mouseup)="myMethod()"

(click)="myMethod()"
(dblclick)="myMethod()"

(drag)="myMethod()"
(dragover)="myMethod()"
(drop)="myMethod()"








sábado, 16 de junho de 2018

Data Attributes – O que são e como usar


Olá, hoje eu vou falar sobre algo que eu particularmente acho muito legal do HTML 5, que são os Data Attributes, ou simplesmente atributos de dados (data-*). Não é algo novo, rsrsrs mas muitas pessoas não usam e muitas usam e nem entendem o que estão fazendo. Você já precisou recuperar no JavaScript valores de um <li>, <ul>, <div> ou qualquer outra tag que não lhe dê a opção de retornar valores como as tags<input>? Bom, com os Data Attributes isso é possível.

O HTML 5 foi desenvolvido para ser extensível, podendo ter dados associados a um elemento específico através de atributos mesmo que esses atributos não tenham sido definidos pela linguagem. Ou seja, podemos adicionar informações a atributos não padrão do HTML e depois recuperar essas informações para usá-las de alguma forma.

Esses atributos valorados não devem conter nenhuma informação confidencial, pois ficam expostos no HTML. Servem para facilitar a manipulação de informações no JavaScript e CSS. Com ele podemos adicionar informações em links, botões, formulários, etc.

A forma de usar é bastante simples, basta declarar um atributo data-* e atribuir o valor desejado. Ex:

<article
  id="carrosEletricos"
  data-columns="3"
  data-index-number="12314"
  data-parent="carros">
...
</article>

Uma vez tendo criado os atributos podemos acessá-los via JavaScript de várias formas e trabalhar em cima dos valores, inclusive alterando-os.

Podemos acessar o valor do atributo diretamente através de um método disponibilizado para varrer os atributos dos elementos HTML - element.getAttribute(“nomeDoAtributo”);. Caso o atributo não exista, o valor retornado será null ou “”. Esse método pode ser usado para atributos padrões do HTML ou os Data Attributes criados. Ex:

<script>
var artigo = document.getElementById(‘carrosEletricos’);
var atributo = artigo.getAttribute(“columns”);
</script>

Mas o padrão recomendado é usando a propriedade dataset do DOMStringMap para recuperar os dados, então teríamos:

<script>
var article = document.getElementById(‘carrosEletricos’);

var colunas = article.dataset.columns; // "3"
var index = article.dataset.indexNumber; // "12314"
var pai = article.dataset.parent; // "carros"
// setar um valor
article.dataset.columns = 5;
</script>

          É claro que podemos também acessar via JQuery:

<script>
var artigo = $("#carrosEletricos");

var colunas = artigo.data("columns"); // "3"
var index = artigo.data("indexNumber"); // "12314"
var pai = artigo.data("parent"); // "cars"
</script>

Abaixo segue um outro exemplo onde temos uma lista de funcionários onde queremos armazenar alguns valores como matricula, idade e sexo, mas não mostrá-los na tela:

<ul>
  <li data-matricula="001" data-idade="23" data-sexo="M" onclick="chamaFuncao(this)">Pedro</li>
  <li data-matricula="002" data-idade="28" data-sexo="M" onclick="chamaFuncao(this)">Daniel</li>
  <li data-matricula="003" data-idade="30" data-sexo="F" onclick="chamaFuncao(this)">Joana</li>
</ul>

Os atributos criados também podem ser usados diretamente no CSS, para isto vamos voltar ao exemplo da tag artigo. Para mostrar o atributo data-parent como conteúdo poderíamos ter o código abaixo:


article::before {
  content: attr(data-parent);
}

Ou usar os “Attribute Selectors” – atributos seletores, que correspondem a elementos com base em seu valor ou simplesmente em sua existência:

// baseado na existência:
article[data-columns] {
       border-right: 1px #bbdefb groove;
}

// baseado no valor:
article[data-columns='3'] {
       width: 400px;
}

article[data-columns='4'] {
       width: 600px;
}

Quando usado por valor, o CSS traz várias opções de comparação e não apenas o “=”. Essas opções funcionam como as Regex do Java ou RegExp do JavaScript. Veja os exemplos:
  
Consideremos o HTML abaixo:

<ul>
  <li><a href="#internal">Internal link</a></li>
  <li><a href="http://example.com">Example link</a></li>
  <li><a href="#InSensitive">Insensitive internal link</a></li>
  <li><a href="http://example.org">Example org link</a></li>
</ul>

<div lang="en-us en-gb en-au en-nz">Hello World!</div>
<div lang="pt">Olá Mundo!</div>
<div lang="zh-CN">世界您好!</div>
<div lang="zh-TW">世界您好!</div>
<div data-lang="zh-TW">?世界您好!</div>


Tendo então as seguintes regras CSS:

a {
  color: blue;
}

/* links internos, começando com "#" */
a[href^="#"] {
  background-color: gold;
}

/* Links com "example" em qualquer parte da URL */
a[href*="example"] {
  background-color: silver;
}

/* Links com "insensitive" em qualquer parte da URL,
   desconsiderando letras maiúsculas e minúsculas -> (i) */
a[href*="insensitive" i] {
  color: cyan;
}

/* Links que terminam ".org" */
a[href$=".org"] {
  color: red;
}

/* Todas as divs com atributo 'lang' são bold. */
div[lang] {
  font-weight: bold;
}

/* Todas as divs em US são azuis. */
div[lang~="en-us"] {
  color: blue;
}

/* Todas as divs em Português são verdes. */
div[lang="pt"] {
  color: green;
}

/* Representa elementos com um nome de atributo
   cujo valor pode ser exatamente igual ou pode
   começar com valor imediatamente seguido por um hífen( - ).
   É frequentemente usado para correspondências de subcódigo
   de idioma.
   Todas as divs em Chinês são vermelhas, mesmo se
    simplificado (zh-CN) ou tradicional (zh-TW). */
div[lang|="zh"] {
  color: red;
}

/* Todas as divs com 'data-lang' Chinês Traditional
   são roxas. */
div[data-lang="zh-TW"] {
  color: purple;
}

Os resultados seriam:



Espero que possa ter ajudado, seguem os links que usei para fazer esse post: