Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →
Apostila Angular - parte 2

Rotas - Router

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

O Angular Router é um poderoso roteador JavaScript construído e mantido pela equipe do Angular Core que pode ser instalada a partir do @angular/routerpacote. Ele fornece uma biblioteca de roteamento completa com a possibilidade de ter várias saídas de roteador, diferentes estratégias de correspondência de caminho, fácil acesso aos parâmetros de roteamento e guardas de rota para proteger os componentes contra acesso não autorizado.

O roteador Angular é uma parte essencial da plataforma Angular. Ele permite que os desenvolvedores criem aplicativos de página única com várias visualizações e permitam a navegação entre essas visualizações.

O Angular Router permite a navegação de uma view para a próxima conforme os usuários executam as tarefas da aplicação.

Visão geral

O navegador é um modelo familiar de navegação de aplicativos:

  • Digite um URL na barra de endereços e o navegador navega para uma página correspondente.
  • Clique nos links na página e o navegador navega para uma nova página.
  • Clique nos botões Voltar e Avançar do navegador e o navegador navega para trás e para frente no histórico de páginas que você viu.

O Angular Router("o roteador") empresta esse modelo. Ele pode interpretar uma URL do navegador como uma instrução para navegar para uma visualização gerada pelo cliente. Ele pode passar parâmetros opcionais ao componente de visualização de suporte que o ajudam a decidir qual conteúdo específico apresentar. Você pode vincular o roteador a links em uma página e ele navegará para a visualização do aplicativo apropriada quando o usuário clicar em um link. Você pode navegar imperativamente quando o usuário clica em um botão, seleciona em uma caixa suspensa ou em resposta a algum outro estímulo de qualquer origem. E o roteador registra a atividade no diário de histórico do navegador para que os botões de voltar e avançar também funcionem

Comando criação de rota manualmente:

ng generate module app-routing --flat --module=app

Onde:

Comando Descrição
- -flat Flag que indica se deve ser criado um diretório no qual os arquivos do componente serão colocados. Valor padrão: true.
- -module <string> Define para qual módulo da aplicação este componente deve ser criado.

Configuração:

Um aplicativo Angular roteado tem uma instância singleton do Routerserviço. Quando o URL do navegador muda, esse roteador procura um correspondente Route do qual possa determinar o componente a ser exibido.

Um roteador não tem rotas até você configurá-lo. O exemplo a seguir cria cinco definições de rotas, configura o roteador através do RouterModule.forRoot()método, e adiciona o resultado ao AppModule's importsmatriz.

const appRoutes: Routes = [ { path: 'crisis-center', component: CrisisListComponent }, { path: 'hero/:id', component: HeroDetailComponent }, { path: 'heroes', component: HeroListComponent, data: { title: 'Heroes List' }}, { path: '', redirectTo: '/heroes', pathMatch: 'full'}, { path: '**', component: PageNotFoundComponent } ];

A appRoutes matriz de rotas descreve como navegar. Passe para o RouterModule.forRoot() método no módulo importspara configurar o roteador.

Cada Route um mapeia um URL pathpara um componente. Não há barras principais no caminho . O roteador analisa e constrói o URL final para você, permitindo que você use os caminhos relativo e absoluto ao navegar entre os modos de exibição do aplicativo.

A :id segunda rota é um token para um parâmetro de rota. Em um URL como /hero/42"42" é o valor do idparâmetro. O correspondente HeroDetailComponent usará esse valor para encontrar e apresentar o herói cujo id42 é. Você aprenderá mais sobre os parâmetros de rota mais adiante neste guia.

A data propriedade na terceira rota é um local para armazenar dados arbitrários associados a essa rota específica. A propriedade de dados é acessível dentro de cada rota ativada. Use-o para armazenar itens como títulos de páginas, texto de trilhas e outros dados estáticossomente leitura . Você usará o protetor de resolução para recuperar dados dinâmicos posteriormente no guia.

O caminho vazio na quarta rota representa o caminho padrão para o aplicativo, o local a ser percorrido quando o caminho na URL está vazio, como normalmente é no início. Essa rota padrão redireciona para a rota da /heroesURL e, portanto, exibirá a HeroesListComponent.

O caminho na última rota é um curinga . O roteador selecionará essa rota se a URL solicitada não corresponder a nenhum caminho para as rotas definidas anteriormente na configuração. Isso é útil para exibir uma página "404 - Não encontrado" ou redirecionar para outra rota.

A ordem das rotas na configuração é importante e isso é por design. O roteador usa uma estratégia de ganhos de primeira partida ao combinar rotas, portanto rotas mais específicas devem ser colocadas acima de rotas menos específicas. Na configuração acima, as rotas com um caminho estático são listadas primeiro, seguidas por uma rota de caminho vazia, que corresponde à rota padrão. A rota curinga vem por último porque corresponde a cada URL e deve ser selecionada apenas se nenhuma outra rota for correspondida primeiro.

Se você precisar ver quais eventos estão ocorrendo durante o ciclo de vida da navegação, há a opção enableTracing como parte da configuração padrão do roteador. Isso produz cada evento de roteador que ocorreu durante cada ciclo de vida de navegação no console do navegador. Isso só deve ser usado para fins de depuração. Você define a enableTracing: trueopção no objeto passado como o segundo argumento para o RouterModule.forRoot()método.

Router-outlet

O Router-Outlet é uma diretiva que está disponível na biblioteca do roteador onde o roteador insere o componente que é correspondido com base na URL do navegador atual. Você pode adicionar várias tomadas em seu aplicativo Angular, o que permite implementar cenários avançados de roteamento.

<router-outlet></router-outlet>

Qualquer componente que seja correspondido pelo roteador o renderizará como um irmão da saída do roteador.

Rotas e Caminhos

Rotas são definições (objetos) compostas de pelo menos um caminho e um componente (ou um redirecionamento para o caminho) atributos. O caminho refere-se à parte da URL que determina uma visualização exclusiva que deve ser exibida, e o componente refere-se ao componente Angular que precisa ser associado a um caminho. Com base em uma definição de rota que fornecemos (por meio de um RouterModule.forRoot (routes)método estático ), o roteador é capaz de navegar pelo usuário para uma visualização específica.

Cada Route mapeia um URL pathpara um componente. O caminho pode estar vazio, o que denota o caminho padrão de um aplicativo e geralmente é o início do aplicativo.

O caminho pode ter uma sequência curinga ( ** ). O roteador selecionará essa rota se a URL solicitada não corresponder a nenhum caminho para as rotas definidas. Isso pode ser usado para exibir uma exibição "Não encontrado" ou redirecionar para uma exibição específica se nenhuma correspondência for encontrada.

Este é um exemplo de uma rota:

{ path: 'contacts', component: ContactListComponent}

Se essa definição de rota for fornecida para a configuração do roteador, o roteador renderizará ContactListComponent quando a URL do navegador para o aplicativo da web se tornar /contacts.

Estratégias de correspondência de Rota:
O roteador angular fornece diferentes estratégias de correspondência de rotas. A estratégia padrão é simplesmente verificar se o URL do navegador atual é prefixado com o caminho.

Por exemplo, nossa rota anterior

{ path: 'contacts', component: ContactListComponent}

Poderia também ser escrito como:

{ path: 'contacts',pathMatch: 'prefix', component: ContactListComponent}

O patchMathatributo especifica a estratégia de correspondência. Neste caso, é o prefixo que é o padrão. A segunda estratégia de correspondência está cheia . Quando for especificado para uma rota, o roteador verificará se o caminho é exatamente igual ao caminho do URL do navegador atual:

{ path: 'contacts',pathMatch: 'full', component: ContactListComponent}

Router Params

Criar rotas com parâmetros é um recurso comum em aplicativos da web. Roteador Angular permite acessar parâmetros de diferentes maneiras:

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →
Usando o serviço ActivatedRoute ,
Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →
Usando o ParamMap observável disponível começando com v4.

Você pode criar um parâmetro de rota usando a sintaxe de dois pontos . Este é um exemplo de rota com um parâmetro id :

{ path: 'contacts/:id', component: ContactDetailComponent}

As RouterLink diretivas nas tags de âncora dão ao roteador controle sobre esses elementos. Os caminhos de navegação são fixos, então você pode atribuir uma string à routerLink(uma ligação "one-time").

Se o caminho de navegação fosse mais dinâmico, você poderia ter vinculado a uma expressão de modelo que retornou uma matriz de parâmetros de link de rota (a matriz de parâmetros de link). O roteador resolve esse array em um URL completo.

Guarda de Rotas

Um roteador de rotas é um recurso do Roteador Angular que permite aos desenvolvedores executar alguma lógica quando uma rota é solicitada e, com base nessa lógica, permite ou nega o acesso do usuário à rota. É comumente usado para verificar se um usuário está logado e tem autorização antes que ele possa acessar uma página.

Você pode adicionar um protetor de rota implementando a CanActivateinterface disponível no @angular/routerpacote e estendendo o canActivate()método que contém a lógica para permitir ou negar o acesso à rota. Por exemplo, a guarda a seguir sempre permitirá o acesso a uma rota:

class MyGuard implements CanActivate { canActivate() { return true; } }

Você pode então proteger uma rota com o guarda usando o canActivateatributo:

{ path: 'contacts/:id, canActivate:[MyGuard], component: ContactDetailComponent}

Diretiva de Navegação

O roteador angular fornece a routerLinkdiretiva para criar links de navegação. Essa diretiva leva o caminho associado ao componente para navegar. Por exemplo:

<a [routerLink]="'/contacts'">Contacts</a>

Múltiplas saídas e Rotas auxiliares

Roteador Angular suporta múltiplas tomadas no mesmo aplicativo. Um componente tem uma rota principal associada e pode ter rotas auxiliares. Rotas auxiliares permitem que os desenvolvedores naveguem em várias rotas ao mesmo tempo.
Para criar uma rota auxiliar, você precisará de uma saída de roteador com nome, na qual o componente associado à rota auxiliar será exibido.

<router-outlet></router-outlet> <router-outlet name="outlet1"></router-outlet>

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →
A saída sem nome é a saída primária.
Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →
Todas as tomadas devem ter um nome, exceto a saída principal.

Você pode então especificar a tomada onde deseja renderizar seu componente usando o atributo outlet:

{ path: "contacts", component: ContactListComponent, outlet: "outlet1" }

Comandos de Instalação

Angular Material

ng add @angular/material

? Choose a prebuilt theme name, or "custom" for a custom theme: Indigo/Pink
Indigo/Pink [ Preview: https://material.angular.io?theme=indigo-pink ]
Deep Purple/Amber [ Preview: https://material.angular.io?theme=deeppurple-amber ]
Pink/Blue Grey [ Preview: https://material.angular.io?theme=pink-bluegrey ]
Purple/Green [ Preview: https://material.angular.io?theme=purple-green ]

#Set up HammerJS for gesture recognition? (Y/n) = Y
#? Set up browser animations for Angular Material? (Y/n) = Y

Vá para app > angular-material.module.ts e adicione o codigo.

import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; import { AppComponent } from './app.component'; import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; @NgModule({ declarations: [ AppComponent ], imports: [ BrowserModule, BrowserAnimationsModule ], providers: [], bootstrap: [AppComponent] }) export class AppModule { }

Material Design Bootstrap

npm i npm-registry-client ng add angular-bootstrap-md

JWT

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →
NPM JWT

O JSON Web Token (JWT) é um padrão aberto ( RFC 7519 ) que define uma maneira compacta e independente de transmitir informações com segurança entre as partes como um objeto JSON. Essas informações podem ser verificadas e confiáveis ​​porque são assinadas digitalmente. Os JWTs podem ser assinados usando um segredo (com o algoritmo HMAC ) ou um par de chaves pública / privada usando RSA ou ECDSA .

Embora as JWTs possam ser criptografadas para também fornecer sigilo entre as partes, focaremos nos tokens assinados . Os tokens assinados podem verificar a integridade das reivindicações contidas nele, enquanto os tokens criptografados ocultam essas reivindicações de outras partes. Quando os tokens são assinados usando pares de chaves pública / privada, a assinatura também certifica que apenas a parte que detém a chave privada é a pessoa que a assinou.

Tecnicamente o que é ?

Após o registro quando o usuário faz o pedido de login .

  1. O servidor verifica se o usuário é legítimo e responde com um token(JWT) contendo a identidade do usuário.
  2. O token em resposta é armazenado localmente no sistema do cliente e o usuário é permitido dentro do aplicativo.
  3. Quando o usuário faz alterações em seu perfil, seu perfil [dados + token] é enviado para o servidor.
  4. O servidor primeiro verifica se o pedido contém o token (responde com um erro se não for passado). O token é então verificado, uma vez feito, os dados do perfil da carga são verificados e as respectivas alterações são feitas no banco de dados.
  5. É o mesmo para todas as outras ações feitas pelo usuário.
  6. Quando o usuário “desconecta” o token de identificação é destruído do local.

O JWT é um padrão (RFC-7519) de mercado que define como transmitir e armazenar objetos JSON de forma compacta e segura entre diferentes aplicações. Os dados nele contidos podem ser validados a qualquer momento pois o token é assinado digitalmente.

Quando você deve usar JSON Web Tokens?

Aqui estão alguns cenários em que JSON Web Tokens são úteis:

  • Autorização: este é o cenário mais comum para o uso do JWT. Após o login do usuário, cada solicitação subsequente incluirá o JWT, permitindo que o usuário acesse rotas, serviços e recursos permitidos com esse token. O Logon único é um recurso que usa amplamente o JWT atualmente, devido à sua pequena sobrecarga e à capacidade de ser facilmente usado em diferentes domínios.

  • Troca de informações: os JSON Web Tokens são uma boa maneira de transmitir informações com segurança entre as partes. Como as JWTs podem ser assinadas (por exemplo, usando pares de chaves públicas / privadas), você pode ter certeza de que os remetentes são quem eles dizem que são. Além disso, como a assinatura é calculada usando o cabeçalho e a carga, você também pode verificar se o conteúdo não foi violado.

Seções do JWT

Ele é formado por três seções: Header, Payload e Signature.

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →
Header
O Header é um objeto JSON que define informações sobre o tipo do token (typ), nesse caso JWT, e o algorítmo de criptografia usado em sua assinatura (alg), normalmente HMAC SHA256 ou RSA.
Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →
Payload
O Payload é um objeto JSON com as Claims (informações) da entidade tratada, normalmente o usuário autenticado.
Essas claims podem ser de 3 tipos:

  • Reserved claims(Reivindicações registradas): atributos não obrigatórios (mas recomendados) que são usados na validação do token pelos protocolos de segurança das APIs.
    • sub (subject) = Entidade à quem o token pertence, normalmente o ID do usuário;
    • iss (issuer) = Emissor do token;
    • exp (expiration) = Timestamp de quando o token irá expirar;
    • iat (issued at) = Timestamp de quando o token foi criado;
    • aud (audience) = Destinatário do token, representa a aplicação que irá usá-lo.

Geralmente os atributos mais utilizados são: sub, iss e exp.

  • Public claims(Reivindicações públicas): atributos que usamos em nossas aplicações. Normalmente armazenamos as informações do usuário autenticado na aplicação.
    • name
    • roles
    • permissions
  • Private claims(Reivindicações privadas): atributos definidos especialmente para compartilhar informações entre aplicações.

Observe que, para tokens assinados, essas informações, embora protegidas contra adulteração, são legíveis por qualquer pessoa. Não coloque informações secretas na carga útil ou nos elementos de cabeçalho de um JWT, a menos que estejam criptografados.

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →
Signature
A assinatura é a concatenação dos hashes gerados a partir do Header e Payload usando base64UrlEncode, com uma chave secreta ou certificado RSA.
Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

Essa assinatura é utilizada para garantir a integridade do token, no caso, se ele foi modificado e se realmente foi gerado por você.

Isso previne ataques do tipo man-in-the-middle, onde o invasor poderia interceptar a requisição e modificar seu conteúdo, desta forma personificando o usuário com informações falsas. Caso o payload seja alterado, o hash final não será válido pois não foi assinado com sua chave secreta.

Apenas quem está de posse da chave pode criar, alterar e validar o token.

Juntando tudo

A saída são três seqüências de caracteres Base64-URL separadas por pontos que podem ser passadas facilmente nos ambientes HTML e HTTP, além de serem mais compactas quando comparadas aos padrões baseados em XML, como SAML.

A seguir, é mostrado um JWT com o cabeçalho e a carga útil anteriores codificados e assinado com um segredo.


Usando o token

Ao fazer login em um serviço de autenticação um token JWT é criado e retornado para o client. Esse token deve ser enviado para as APIs através do header Authorization de cada requisição HTTP com a flag Bearer, conforme ilustra o diagrama abaixo.

Authorization: Bearer token

Diagrama de sequência usando token JWT

Em posse do token, a API não precisa ir até o banco de dados consultar as informações do usuário, pois contido no próprio token JWT já temos suas credenciais de acesso.

JWT, resumidamente, é uma string de caracteres codificados que, caso cliente e servidor estejam sob HTTPS, permite que somente o servidor que conhece o ‘segredo’ possa ler o conteúdo do token, e assim confirmar a autenticidade do cliente.

Ou seja, quando um usuário se autentica no sistema (com usuário e senha), o servidor gera um token com data de expiração pra ele. Durante as requisições seguintes do cliente, o JWT é enviado no cabeçalho da requisição e, caso esteja válido, a API irá permitir acesso aos recursos solicitados, sem a necessidade de se autenticar novamente.

O conteúdo do JWT é um payload JSON que pode conter a informação que você desejar, que lhe permita mais tarde conceder autorização a determinados recursos para determinados usuários. Minimamente ele terá o ID do usuário autenticado, mas pode conter muito mais do que isso. saiba a diferença, autenticação é você provar que você é você mesmo. Já autorização, é você provar que possui permissão para fazer ou ver o que você está tentando.

Antes de emitir o JWT, é necessário que o usuário passe por uma autenticação tradicional, geralmente com usuário e senha. Essa informação fornecida é validada junto a uma base de dados e somente caso ela esteja ok é que geramos o JWT para ele.

Material Design Bootstrap

O Material Design for Bootstrap é um kit de ferramentas de código aberto baseado no Bootstrap para desenvolver aplicativos de Material Design com HTML, CSS e JS. Crie rapidamente protótipos de suas ideias ou construa seu aplicativo inteiro com nossas variáveis e mixins Sass, sistema de grade responsivo, extensos componentes pré-construídos e poderosos plugins construídos em jQuery.

Desenvolvido em 2014 pelo Google, o Material Design é uma “linguagem de design” . Ele é baseado nos motivos de "cartão" que foram introduzidos pela primeira vez no Google Now e expandiu isso, incluindo transições e animações responsivas, efeitos como iluminação e sombras e layouts baseados em grade.

Sendo uma linguagem de design, o Material Design define um conjunto de diretrizes que mostram como melhor projetar um website. Ele informa quais botões são para uso e quais você deve usar, como animar ou movê-lo, bem como onde e como ele deve ser colocado, etc.

É uma linguagem de design para dispositivos móveis , que pode ser usada em todas as versões compatíveis do Android, proporcionando uma experiência consistente e de qualidade em todos os aplicativos e plataformas Android, que também podem ser expandidos para outras plataformas e aplicativos, principalmente por meio de APIs para desenvolvedores de terceiros.

Além da facilidade de implementação e uso, outro grande recurso dessa plataforma de design é a falta de dependência de estruturas e bibliotecas JavaScript .

Em vez disso, ele se baseia em uma estrutura de design de materiais que facilita a utilização e fornece modelos personalizáveis e proporcionam muita liberdade criativa, ajudando a criar sites que se destacam.

Comandos para instalar

npm i npm-registry-client ng add angular-bootstrap-md

Angular Material

O Angular Material é um pacote de terceiros usado em projetos Angular para facilitar o processo de desenvolvimento através da reutilização de componentes comuns, como cartões, belas entradas, tabelas de dados e assim por diante. A lista de componentes disponíveis é grande e continua a crescer enquanto falamos. Portanto, para obter uma referência completa dos componentes com exemplos, consulte o site oficial .

Com o Angular, o aplicativo inteiro é uma composição de componentes e, em vez de criar e modelar componentes do grupo, você pode aproveitar o Material Angular, que fornece componentes estilizados prontos para uso que seguem as Especificações de design do material .

Essa especificação é usada pelo Google no sistema operacional Android e também é muito popular na Web devido a seus belos utilitários de interface do usuário.

Instalações

Material Angular

ng add @angular/material

Flexbox

npm install @angular/flex-layout@v5.0.0-beta.14 rxjs-compat

No app.module.ts

import {FlexLayoutModule} from '@angular/flex-layout'; @NgModule({ imports: [ FlexLayoutModule, ], }) export class AppModule {}

Animate css

O Animate é o grande astro por trás de toda a magia que vocês estão prestes a testemunhar neste artigo. O Animate.css é um projeto idealizado por Daniel Eden — atualmente designer de produto no Facebook. Como diz em sua descrição no GitHub, o projeto é uma série de animações legais, leves e divertidas para você usar nos seus projetos. Na sua página oficial, temos uma demo de todas as animações que podemos colocar nos nossos elementos. São mais de 30 animações muito bem feitas.

Wow js

Essa biblioteca javascript nos auxilia a criar animações que acontecem de acordo com o scroll do usuário no nosso site. Ela se casa muito bem com o animate.css e nos permite configurar uma série de atributos.

Jarallax

Jarallax é uma biblioteca javascript de código aberto que facilita o ajuste do css baseado na interação. Com Jarallax é fácil criar um site de rolagem paralaxe.

Fontawesome

Font Awesome é um conjunto de ferramentas de fontes e ícones com base em CSS e LESS. Foi feito por Dave Gandy para uso com o Twitter Bootstrap e mais tarde foi incorporado no BootstrapCDN. Font Awesome tem uma participação de mercado de 20% entre os sites que usam Font Scripts de terceiros em sua plataforma, classificando o segundo lugar após o Google Fonts,

O Font Awesome é uma biblioteca de ícones e ferramentas baseada em CSS e fontes. Ela oferece uma ampla variedade de ícones vetoriais que podem ser facilmente utilizados em projetos web e de design. Aqui estão alguns pontos-chave sobre o Font Awesome:

  1. Ícones Vetoriais: Ao contrário das imagens tradicionais, os ícones do Font Awesome são vetoriais, o que significa que podem ser dimensionados sem perder qualidade ou nitidez. Isso é especialmente útil em projetos responsivos, onde os elementos precisam se adaptar a diferentes tamanhos de tela.
  2. Fácil Implementação: O Font Awesome pode ser facilmente implementado em projetos web através de várias formas, como CDN (Content Delivery Network), download local dos arquivos ou integração com ferramentas de desenvolvimento como o npm.
  3. Personalização: A biblioteca oferece opções de personalização dos ícones, como tamanho, cor, sombra, entre outros, utilizando classes CSS específicas.
  4. Variedade de Ícones: O Font Awesome possui uma vasta coleção de ícones para diversas categorias, como tecnologia, negócios, mídia social, interface do usuário, entre outros. Isso permite aos desenvolvedores e designers encontrar facilmente os ícones adequados para seus projetos.
  5. Compatibilidade: Os ícones do Font Awesome são compatíveis com a maioria dos navegadores modernos, garantindo uma experiência consistente para os usuários.
  6. Facilidade de Uso: A integração dos ícones é simples, exigindo apenas a inclusão das classes CSS apropriadas nos elementos HTML onde os ícones devem ser exibidos.

O Font Awesome é uma ferramenta valiosa para adicionar ícones de alta qualidade e escaláveis em projetos web, proporcionando uma experiência visual atraente e funcional aos usuários.
.
.
.

LocalStorage

LocalStorage e SessionStorage, parte da API de armazenamento da web, são duas ótimas ferramentas para salvar pares chave / valor localmente. Se você clicar no botão Salvar na parte superior desta postagem, o localStorage é o que é usado para armazenar suas postagens salvas.

Tanto o localStorage quanto o sessionStorage oferecem vantagens em comparação ao uso de cookies:

  • Os dados são salvos apenas localmente e não podem ser lidos pelo servidor, o que elimina o problema de segurança que os cookies apresentam.
  • Ele permite que muito mais dados sejam salvos ( 10Mb para a maioria dos navegadores).
  • É mais simples de usar e a sintaxe é muito simples.
  • Também é suportado em todos os navegadores modernos, para que você possa usá-lo hoje sem problemas. Obviamente, como os dados não podem ser lidos no servidor, os cookies ainda têm um uso, especialmente quando se trata de autenticação.

LocalStorage vs SessionStorage

localStorage e sessionStorage realizam exatamente a mesma coisa e têm a mesma API, mas com sessionStorage os dados são mantidos até que a janela ou a guia seja fechada, enquanto com localStorage os dados persistem até que o usuário limpe manualmente o cache do navegador ou até o aplicativo da web limpa os dados. Os exemplos nesta postagem são para localStorage, mas a mesma sintaxe funciona para sessionStorage.

Usando o localStorage

O localStorage salva dados no computador do visitante, que ficam vinculados ao (e apenas acessíveis pelo) seu domínio. E pra usar é bem simples:

Use o método setItem(nome, valor) para criar/salvar novos itens e o depois o método getItem(nome) para recuperar o valor.

// Cria um item "usuario" com valor "Belem" window.localStorage.setItem('usuario', 'Belem'); // Depois, em outra página ou aba, recupera esse item var usuario = window.localStorage.getItem('usuario'); // Remove o item window.localStorage.removeItem('usuario');

Usando o sessionStorage

Já o sessionStorage faz exatamente a mesma coisa, só que os dados ficam salvos apenas durante a sessão (e são apagados quando o visitante fecha a aba/navegador):

Diretivas

Como seu elemento DOM (Modelo de Objeto de Documento) se comporta de uma certa maneira, sim, você pode fazer isso em Angular. Podemos anexar um comportamento especificado a um elemento DOM em nosso aplicativo angular. Isso é feito com a ajuda de um decorador @Directive.

As diretivas são como um marcador em nossos elementos DOM, que as fazem se comportar de uma maneira especificada. Existem muitas diretivas embutidas no Angular em diferentes categorias que discutiremos daqui a pouco.

Para que usamos diretivas?

As diretivas são usadas principalmente quando queremos um Componente HTML reutilizável, um comportamento HTML reutilizável ou sempre que interagimos com o DOM.

A convenção de nomenclatura seguida pelas diretivas é ng seguida pelo objetivo da diretiva . No entanto, quando criamos nossas próprias diretivas personalizadas, podemos usar qualquer convenção de acordo com nossa conveniência.

Algumas das diretivas mais usadas no Angular são:

  • ng-bind,
  • ng-model,
  • ng-hide,
  • ng-init etc.

Falando sobre os diferentes tipos de diretivas no Angular, existem três tipos de diretivas.

  • Componente
  • Diretivas de Atributos
  • Diretivas de estrutura

Componentes

Componentes são as diretivas mais usadas no Angular que, quando usadas como decorador acima da classe, fazem com que ele se comporte de acordo com o comportamento especificado na definição de diretiva. Estes também são conhecidos como auto-contido directivas.

Os componentes têm seu próprio HTML conhecido como modelo. Um exemplo de um componente está listado abaixo:

@Component ({ seletor: 'app-root', template: `<h1> Olá, eu sou um exemplo de COmponents </h1>` }) classe de exportação AppComponent { }

Diretivas estruturais

Diretivas estruturais são as diretivas usadas para modificar o layout adicionando ou removendo os elementos DOM. São como diretivas condicionais.

As diretivas estruturais mais usadas são * ngIf e * ngFor . Vamos primeiro ver como * ngIf funciona.

@Componente({ seletor: 'app-root', template: `<h2> Bem-vindo </h2> <p * ngIf = "show"> Mostrar </p> ` }) classe de exportação Component { show público = verdadeiro; }

No código acima, se o valor de show for verdadeiro, ele exibirá Show no navegador, senão nada; assim como uma declaração if.

Da mesma forma, uma diretiva * ngFor funciona como um loop for. Vamos ver o código na lista abaixo:

@Componente({ seletor: 'app-root', template: `<h2> Bem-vindo </h2> <p * ngIf = "show"> Mostrar </p> <ul> <li * ngFor = "deixe o item dos itens"> {{item}} </li> </ul> ` }) classe de exportação Component { show público = verdadeiro; item público = 'lápis'; itens públicos = ['borracha', 'apontador', 'caneta', 'lápis', 'geometria']; }

Existem muitas outras diretivas de estrutura como ngSwitch, ngSwitchWhen etc.

Diretivas de Atributos

Agora, quando queremos alterar o atributo, como o nome sugere, a cor, o estilo da fonte, a cor do plano de fundo e a função de uma propriedade, usamos diretivas de atributo nesse caso.

Agora, suponha que eu tenha algum texto no meu navegador e desejo alterar a cor e o tamanho da fonte desse texto. Para fazer isso, eu precisaria usar a diretiva de atributo. Uma coisa mais importante a saber aqui é que também podemos criar nossas próprias diretivas de atributos personalizados e aplicar nossos próprios comportamentos especificados aos objetos, mas abordaremos isso mais tarde.

Vamos ver um exemplo de diretivas de atributo:

@Componente({ seletor: 'app-root', template: `<h2> Bem-vindo </h2> <p [ngStyle] = "{'estilo da fonte': estilo, 'tamanho da fonte': tamanho}"> Meu texto </p> ` }) classe de exportação Component { // show público = true; estilo público = 'itálico'; tamanho público = '30px'; }

TypeOrm

O TypeORM é um ORM que pode ser executado nas plataformas NodeJS, Navegador, Cordova, PhoneGap, Ionic, React Native, NativeScript, Expo e Electron e pode ser usado com TypeScript e JavaScript (ES5, ES6, ES7, ES8). Seu objetivo é sempre oferecer suporte aos recursos mais recentes do JavaScript e fornecer recursos adicionais que o ajudem a desenvolver qualquer tipo de aplicativo que use bancos de dados - desde aplicativos pequenos com algumas tabelas a aplicativos corporativos em larga escala com vários bancos de dados.

O TypeORM suporta os padrões Active Record e Data Mapper , diferentemente de todos os outros ORMs JavaScript existentes no momento, o que significa que você pode escrever aplicativos de alta qualidade, de baixo acoplamento, escalabilidade e manutenção da maneira mais produtiva.

O TypeORM é altamente influenciado por outros ORMs, como Hibernate , Doctrine e Entity Framework

Para criar um projeto TypeOrm

typeorm init --name myproject --database mysql

Comandos para instalação

npm install -g typeorm //instalação global (na maquina) npm install -g ts-node //instalação global (na maquina) npm install typeorm --save //instalação no projeto npm install reflect-metadata --save //instalação no projeto npm install @types/node --save //instalação no projeto

Alguns recursos do TypeORM:

  • suporta DataMapper e ActiveRecord (sua escolha)
  • entidades e colunas
  • tipos de coluna específicos do banco de dados
  • gerente de entidade
  • repositórios e repositórios personalizados
  • modelo relacional de objeto limpo
  • associações (relações)
  • relações ansiosas e preguiçosas
  • relações unidirecionais, bidirecionais e auto-referenciadas
  • suporta vários padrões de herança
  • cascatas
  • índices
  • transações
  • migrações e geração automática de migrações
  • pool de conexão
  • replicação
  • usando várias conexões com o banco de dados
  • trabalhando com vários tipos de bancos de dados
  • consultas entre bancos de dados e esquemas cruzados
  • sintaxe elegante, flexível e poderoso QueryBuilder
  • junções esquerda e interna
  • paginação adequada para consultas usando junções
  • cache de consulta
  • streaming de resultados brutos
  • exploração madeireira
  • ouvintes e assinantes (ganchos)
  • suporta padrão de tabela de fechamento
  • declaração de esquema em modelos ou arquivos de configuração separados
  • configuração de conexão nos formatos json / xml / yml / env
  • suporta MySQL / MariaDB / Postgres / CockroachDB / SQLite / Microsoft SQL Server / Oracle / sql.js
  • suporta banco de dados MongoDB NoSQL
  • trabalha nas plataformas NodeJS / Navegador / Ionic / Cordova / React Native / NativeScript / Expo / Electron
  • Suporte TypeScript e JavaScript
  • O código produzido é de alto desempenho, flexível, limpo e sustentável
  • segue todas as melhores práticas possíveis
  • CLI

Instalação

Instale o pacote npm:

npm install typeorm --save

Você precisa instalar o reflect-metadatashim:

npm install reflect-metadata --save

e importe-o em algum lugar no local global do seu aplicativo (por exemplo, em app.ts):

import "reflect-metadata";

Pode ser necessário instalar as tipagens dos nós:

npm install @types/node --save

Instale um driver de banco de dados:

para MySQL ou MariaDB

npm install mysql --save(você também pode instalar mysql2)

para PostgreSQL ou CockroachDB

npm install pg --save

para SQLite

npm install sqlite3 --save

para Microsoft SQL Server

npm install mssql --save

para sql.js

npm install sql.js --save

para Oracle

npm install oracledb --save

Instale apenas um deles, dependendo do banco de dados que você usa. Para fazer o trabalho driver Oracle, você precisa seguir as instruções de instalação do seu site.

para MongoDB (experimental)

npm install mongodb --save

NestJS

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →
https://nestjs.com/
Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

Documentação: https://docs.nestjs.com/

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

O Nest é uma estrutura para criar aplicativos eficientes e escalonáveis do lado do servidor Node.js. Ele usa JavaScript moderno, é construído com TypeScript (preserva a compatibilidade com JavaScript puro) e combina elementos de OOP (Programação Orientada a Objetos), FP (Programação Funcional) e FRP (Programação Reativa Funcional).

Sob o capô, o Nest faz uso do Express , mas também oferece compatibilidade com uma grande variedade de outras bibliotecas, como, por exemplo , o Fastify , permitindo o fácil uso dos inúmeros plugins de terceiros disponíveis.

Nos últimos anos, graças ao Node.js., o JavaScript se tornou a "língua franca" da Web para aplicativos front-end e back-end, dando origem a projetos incríveis como Angular , React e Vue, que melhoram a produtividade do desenvolvedor e permitem a construção rápida, aplicativos frontend testáveis ​​e extensíveis. No entanto, no lado do servidor, embora existam muitas excelentes bibliotecas, auxiliares e ferramentas para o Node, nenhum deles resolve efetivamente o principal problema - a arquitetura.

O objetivo da Nest é fornecer uma arquitetura de aplicativos pronta para uso, que permita a criação sem esforço de aplicativos altamente testáveis, escaláveis, com acoplamento fraco e de fácil manutenção.

Criar um projeto, instalar e rodar

npm i -g @nestjs/cli //instalar a biblioteca nest new project-name //criar o projeto npm i --save @nestjs/core @nestjs/common rxjs reflect-metadata npm install //instalar o package npm run start //iniciar o projeto

Passport

O Passport.js é um dos middlewares de autenticação mais antigos, conhecidos pelo desenvolvimento do Node.js. Ele fornece um alto nível de flexibilidade em termos de escolha de qual estratégia de autenticação usar para autenticar seus usuários.

O Nest.js oferece a biblioteca de autenticação @ nestjs / passport que agrupa a funcionalidade do Passport.js e se integra perfeitamente ao sistema de Injeção de Dependência do Nest.js.

O Passport.js geralmente é usado e configurado como um Node Middleware. No entanto, no Nest.js, a biblioteca @ nestjs / passport fornece o AuthGuard. Isso é usado para sugerir que a autenticação do Passport é necessária em um Controlador ou Ação específica no Controlador.

Instalação:

npm i @nestjs/passport passport passport-local passport-jwt bcryptjs

Definições de TypeScript correspondentes para os seguintes pacotes executando este comando:

@types/passport @types/bcryptjs -D

Modules

Módulos no Nest.js é a forma básica de construir e agrupar blocos de código de maneira coesa. Para iniciar o Nest.js, nós precisamos informar o módulo raiz da nossa aplicação, logo, a boa prática diz que você deve organizar sua aplicação em um formato de arvore, com um módulo raiz e os seguintes serão suas funcionalidades.

Para informar ao Nest.js qual será o nosso módulo raiz, precisamos utilizar a classe NestFactory para criar, não apenas a raiz mas toda a arvore de módulos.

Controllers

Como em muitas outras plataformas, Java/Spring ou C#/ASP.NET, controllers no Nest.js são resposaveis por auxiliar no trabalho de receber e tratar uma requisição HTTP, para definir um novo controller, é necessário:

  • Expor uma classe nova
  • Utilizar o decorator @Controller()
  • Adicionar a classe em um módulo, mesmo que seja no raiz
  • Decorar algum método com @Get() ou @Post() para receber um requisição get ou post

Providers

Quase tudo pode ser considerado como um provedor – provider – service, repository, factory, helper e assim por diante. Todos eles podem injetar dependências através de construtor (Dependency Injection), ou seja, eles podem criar vários relacionamentos entre si. Mas, na verdade, um provedor nada mais é do que apenas uma classe simples anotada com um decorator @Injectable().

Components

Você pode criar componentes que podem ser injetados, utilizando injeção de dependências, em outros componentes. Usualmente você irá utilizar um Service para programar sua lógica de negócios, e um Repository para programar uma interação com uma forma de persistência de dados, como o banco de dados por exemplo.

Como exemplo, digamos que temos um Service, que finaliza a compra de um carrinho de compras, para isto, o Servicê irá interagir com um Repository verificando se há os itens em estoque.

  • tsconfig.json arquivo para configurar o TypeScript
  • nodemon.json arquivo para configuração do nodemon
  • tslint.json arquivo para aprender TypeScript
  • nest-cli.json para configuração da CLI
  • src/pasta contendo o código real do projeto
  • test/pasta contendo os testes.

Middlewares

Quando queremos agir, antes dos Controllers, nós podemos criar um Middleware implementando a interface NestMiddleware que deve ser decorada com @Middleware(). Esta interface espera que implementemos o método resolve e que retorne um Express Middleware: (req, res, next) => void.

Exception Filters

Temos a nossa disposição uma camada responsável por capturar exceções não tratadas. Nesta camada podemos definir filtros de exceçoes. Para isto, precisamos:

  • Criar uma classe que implemente ExceptionFilter
  • Decorar a classe com @Catch()
  • Implementar o método catch(exception: HttpException, reponse)

Jasmine

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →
https://jasmine.github.io/
Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

Exception filters

A camada de exceções interna é responsável por manipular todas as exceções lançadas em todo o seu aplicativo. Quando uma exceção não tratada é detectada, o usuário final receberá uma resposta adequada.

Pipes

Um pipe é uma classe anotada com o decorator @Injectable(). O pipe deve implementar a interface PipeTransform.

Guards

Um guarda é uma classe anotada com o decorator @Injectable(). O guarda deve implementar a interface do CanActivate.

Interceptors

Um interceptor é uma classe anotada com o decorator @Injectable(). O interceptor deve implementar a interface NestInterceptor.

Jasmine é uma estrutura de desenvolvimento orientada a comportamento para testar o código JavaScript. Não depende de nenhuma outra estrutura JavaScript. Não requer um DOM. E possui uma sintaxe limpa e óbvia, para que você possa escrever facilmente testes. Este guia está sendo executado no Jasmine versão 2.0.0.

Especificações:

As especificações são definidas chamando a função Jasmine global it, que, como describe leva uma string e uma função. A sequência é o título da especificação e a função é a especificação ou teste. Uma especificação contém uma ou mais expectativas que testam o estado do código. Uma expectativa no Jasmine é uma afirmação que é verdadeira ou falsa. Uma especificação com todas as expectativas verdadeiras é uma especificação de aprovação. Uma especificação com uma ou mais expectativas falsas é uma especificação com falha.

São apenas funções:

Como os blocos describe it são funções, eles podem conter qualquer código executável necessário para implementar o teste. As regras de escopo do JavaScript se aplicam, portanto, as variáveis declaradas em describe estão disponíveis para qualquer it bloco dentro do conjunto.

Expectativas:

As expectativas são construídas com a função expect que recebe um valor, chamado de real. É encadeado com uma função Matcher, que aceita o valor esperado.

Matchers:

Cada correspondente implementa uma comparação booleana entre o valor real e o valor esperado. É responsável por relatar ao Jasmine se a expectativa é verdadeira ou falsa. Jasmine passará ou falhará nas especificações.

Qualquer correspondente pode avaliar uma afirmação negativa encadeando a chamada expect com a nota ntes de chamar o correspondente.

Matchers Incluídos

Jasmine tem um rico conjunto de matchers incluídos. Cada um é usado aqui - todas as expectativas e especificações passam. Também é possível escrever correspondências personalizadas para quando o domínio de um projeto solicitar asserções específicas que não estão incluídas abaixo.

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →
toEqual
Esse talvez seja o mais básico e um dos que mais iremos usar. Simplesmente verifica se duas coisas são iguais (e não necessariamente o mesmo objeto).

expect(true).toEqual(true); expect([1, 2, 3]).toEqual([1, 2, 3]);

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →
toBe
O matcher toBe, a princípio, parece ser igual ao toEqual. A diferença é que toBe verifica não só se os dois valores são iguais, mas também se eles são do mesmo objeto.

var bob = { model: "Camaro" }; var john = { model: "Camaro" }; expect(bob).toEqual(john); // passa => são equivalentes expect(bob).toBe(john); // falha => não é o mesmo objeto

Apesar de bob e john serem similares, eles não são o mesmo objeto, o que faz a spec passar se for usado o matcher toEqual, mas falha se for usado o matcher toBe. O mesmo acontece para arrays:

var group = [100, 101, 102]; expect(group).toEqual([100, 101, 102]); // passa => são equivalentes expect(group).toBe([100, 101, 102]); // falha => não é o mesmo array

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →
toBeTruthy e toBeFalsy
Para testar se algum valor é avaliado como true ou false, podemos usar respectivamente os matchers toBeTruthy e toBeFalsy:

expect(true).toBeTruthy(); expect(1000).toBeTruthy(); expect({}).toBeTruthy(); expect("").toBeFalsy(); expect(null).toBeFalsy(); expect(false).toBeFalsy();

Se pararmos pra olhar com calma o exemplo anterior, podemos notar que a avaliação dos matchers toBeTruthy e toBeFalsy é idêntica ao JavaScript. Então, temos alguns valores específicos que são considerados falsy e todo o restante é avaliado como truthy.

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →
not
Muitas vezes podemos inverter um matcher para termos certeza de que ele não é um valor true. Podemos fazer isso facilmente adicionando o prefixo .not:

expect('Beléim').not.toEqual('Belem');

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →
toContain
Conseguimos também verificar se um elemento está contido em um array ou string por exemplo, como o matcher toContain.

expect([10, 11, 12, 13, 14, 15]).toContain(13); expect('Edson Belem').toContain('Belem');

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →
toBeDefined e toBeUndefined
Da mesma maneira que vimos os matchers toBeTruthy e toBeFalsy, Jasmine também nos oferece os toBeDefined e toBeUndefined que verificam se um valor é defined ou undefined.

var iAmUndefined; expect(null).toBeDefined(); // passa expect('Belem').toBeDefined(); // passa expect(iAmUndefined).toBeDefined(); // falha expect(iAmUndefined).toBeUndefined(); // passa expect(12).toBeUndefined(); // falha expect(null).toBeUndefined(); // falha

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →
toBeNull
Direto ao ponto, esse matcher simplesmente avalia se um valor é null:

expect(null).toBeNull(); // passa expect(false).toBeNull(); // falha expect(1).toBeNull(); // falha

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →
toBeNaN
Sem muitas delongas, esse matcher verifica se um valor é NaN:

expect(0).toBeNaN(); // falha expect(10).not.toBeNaN(); // passa

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →
toBeGreatherThan e toBeLessThan
Esses dois matchers verificam se um valor é maior ou menor que um outro valor passado.

expect(10).toBeGreatherThan(1); // passa expect(10).toBeLessThan(20); // passa

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →
toBeCloseTo
Esse matcher permite que possamos verificar se um certo número está próximo de um outro número, dado uma certa precisão decimal como segundo argumento. Poderíamos por exemplo, verificar se um número é próximo de 25.23 com um ponto decimal. Poderíamos fazer algo assim:

expect(25.23).toBeCloseTo(25.2, 1); // passa

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →
toMatch
Esse cara verifica se algum valor está de acordo com base em uma expressão regular.

expect('Yes, we can!').toMatch(/we/); // passa

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →
toThrow
Esse matcher permite que verifiquemos se uma função lançou um erro. Como exemplo, vamos imaginar que temos uma função onlyNumbers que deve lançar uma exceção caso o argumento passado seja uma string e não um número. Podemos usar aqui uma função anônima para nos facilitar a vida:

expect(function() { onlyNumbers('argumento errado') }).toThrow();

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →
Para iniciar o teste

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →
Digitar no terminal:

ng test

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

O comando ng test cria o aplicativo no modo de exibição e inicia o teste de Karma. Aguardar abrir o projeto no browser. Aparecerá os testes que foram feitos e os que estão comentados (pendentes)


A saída do console se parece um pouco com isso:

10% building modules 1/1 modules 0 active
INFO [karma]: Karma v1.7.1 server started at http://0.0.0.0:9876/
INFO [launcher]: Launching browser Chrome
INFO [launcher]: Starting browser Chrome
INFO [Chrome ]: Connected on socket
Chrome : Executed 3 of 3 SUCCESS (0.135 secs / 0.205 secs)

A última linha do log é a mais importante. Isso mostra que o Karma realizou três testes que foram aprovados.


Formulario Reativo

https://angular.io/guide/reactive-forms

Manipular a entrada do usuário com formulários é a pedra angular de muitos aplicativos comuns. Os aplicativos usam formulários para permitir que os usuários efetuem login, atualizem um perfil, insiram informações confidenciais e executem muitas outras tarefas de entrada de dados.

Angular fornece duas abordagens diferentes para lidar com a entrada do usuário por meio de formulários: reativo e orientado a modelo. Ambos capturam eventos de entrada do usuário a partir da visualização, validam a entrada do usuário, criam um modelo de formulário e modelo de dados para atualizar e fornecem uma maneira de rastrear alterações.

Os formulários reativos fornecem uma abordagem orientada a modelo para lidar com entradas de formulário cujos valores mudam ao longo do tempo. Este guia mostra como criar e atualizar um controle básico de formulário, avançar para o uso de vários controles em um grupo, validar valores de formulário e criar formulários dinâmicos nos quais você pode adicionar ou remover controles em tempo de execução.

Visão geral

Os formulários reativos usam uma abordagem explícita e imutável para gerenciar o estado de um formulário em um determinado momento. Cada mudança no estado do formulário retorna um novo estado, que mantém a integridade do modelo entre as mudanças. Os formulários reativos são construídos em torno de fluxos observáveis , em que entradas e valores de formulário são fornecidos como fluxos de valores de entrada, que podem ser acessados ​​de forma síncrona.

Os formulários reativos também fornecem um caminho direto para o teste, porque você tem certeza de que seus dados são consistentes e previsíveis quando solicitados. Qualquer consumidor dos fluxos tem acesso para manipular esses dados com segurança.

Os formulários reativos diferem dos formulários orientados a modelos de maneiras distintas. Os formulários reativos fornecem mais previsibilidade com acesso síncrono ao modelo de dados, imutabilidade com operadores observáveis ​​e rastreamento de alterações através de fluxos observáveis.

Os formulários controlados por modelo permitem acesso direto para modificar dados em seu modelo, mas são menos explícitos que os formulários reativos, porque contam com diretivas incorporadas ao modelo, juntamente com dados mutáveis ​​para rastrear alterações de forma assíncrona. Consulte a Visão geral dos formulários para comparações detalhadas entre os dois paradigmas.

Escolhendo uma abordagem

Formulários reativos e formulários controlados por modelo processam e gerenciam dados de formulário de maneira diferente. Cada abordagem oferece vantagens diferentes.

  • Os formulários reativos fornecem acesso direto e explícito ao modelo de objeto de formulários subjacente. Comparados aos formulários orientados a modelos, eles são mais robustos: são mais escaláveis, reutilizáveis ​​e testáveis. Se os formulários são uma parte essencial do seu aplicativo, ou você já está usando padrões reativos para criar seu aplicativo, use formulários reativos.

  • Formulários controlados por modelo dependem de diretrizes no modelo para criar e manipular o modelo de objeto subjacente. Eles são úteis para adicionar um formulário simples a um aplicativo, como um formulário de inscrição na lista de emails. Eles são fáceis de adicionar a um aplicativo, mas não são dimensionados tão bem quanto em formas reativas. Se você possui requisitos e lógica de formulário muito básicos que podem ser gerenciados apenas no modelo, os formulários controlados por modelo podem ser uma boa opção.

Principais diferenças

REATIVO ORIENTADO A MODELOS
Configuração do modelo de formulário Explícito, criado na classe de componente Implícito, criado por diretivas
Modelo de dados Estruturado e imutável Não estruturado e mutável
Previsibilidade Síncrono Assíncrono
Validação de formulário Funções Diretivas

Escalabilidade

Se os formulários são uma parte central do seu aplicativo, a escalabilidade é muito importante. Ser capaz de reutilizar modelos de formulário entre componentes é fundamental.

Formulários reativos são mais escaláveis ​​que formulários controlados por modelo. Eles fornecem acesso direto à API do formulário subjacente e acesso síncrono ao modelo de dados do formulário, facilitando a criação de formulários em grande escala. Os formulários reativos requerem menos configuração para o teste, e o teste não requer um entendimento profundo da detecção de alterações para testar adequadamente as atualizações e a validação do formulário.

Os formulários orientados a modelos concentram-se em cenários simples e não são tão reutilizáveis. Eles abstraem a API do formulário subjacente e fornecem apenas acesso assíncrono ao modelo de dados do formulário. A abstração de formulários controlados por modelo também afeta o teste. Os testes dependem profundamente da execução manual da detecção de alterações para serem executados corretamente e exigem mais configurações.


Acesso direto ao modelo de formulários de forma reativa.


Acesso indireto ao modelo de formulários em um formulário controlado por modelo.


Lazy Loading

Lazy loading é o processo de carregamento de módulos (imagens, vídeos, documentos, JS, CSS, etc) sob demanda.

Os conceitos mais importantes de desempenho do aplicativo são: Tempo de Resposta e Consumo de Recursos. É inevitável que isso aconteça. Além disso, um problema pode surgir de qualquer lugar, mas é muito importante encontrá-los e resolvê-los antes que aconteçam.

A perspectiva de Lazy Loading no Angular ajuda a reduzir ao mínimo o risco de alguns dos problemas de desempenho do aplicativo da web. O Lazy Loading faz bem em verificar os conceitos listados acima:

  • Tempo de resposta : é a quantidade de tempo que o aplicativo da web leva para carregar e a interface de IU para responder aos usuários. O carregamento lento otimiza o tempo de resposta dividindo o código e carregando o pacote desejado.
  • Consumo de recursos : os humanos são criaturas impacientes se um site leva mais de 3 segundos para carregar, 70% de nós desistiremos. Os aplicativos da web não devem demorar tanto para carregar. Portanto, para reduzir a quantidade de carregamento de recursos, o carregamento lento carrega o pacote de código necessário por vez.

O carregamento lento acelera o tempo de carregamento de nosso aplicativo, dividindo-o em vários pacotes e carregando-os sob demanda.

Vantagens do carregamento lento:

  • Alto desempenho em tempo de bootstrap na carga inicial.
  • Os módulos são agrupados de acordo com sua funcionalidade.
  • Pacotes de código menores para download no carregamento inicial.
  • Ative / baixe um módulo de código navegando para uma rota.
  • O carregamento lento não carrega tudo uma vez, ele carrega apenas o que o usuário espera ver primeiro.

Como funciona o Lazy Loading?

O Lazy Loading geralmente é um conceito em que atrasamos o carregamento de um objeto até que ele seja necessário. No Angular, todos os componentes JavaScript declarados na matriz de declarações app.module.tssão agrupados e carregados de uma só vez quando um usuário visita nosso site.

A estrutura

Abaixo a estrutura proposta para projetos de grande porte:

Módulos - Lazy Load

Módulos lazy loaded ajudam a diminuir o tempo de inicialização da aplicação. Com o lazy load, o aplicativo não precisa carregar tudo de uma só vez. Ele só vai carregar o que o usuário espera ver. O módulo só irá carregar quando o usuário navegar para sua rota. Perfeito para aplicações grande, combina com o interesse do usuário e organiza a estrutura. Todo o conteúdo do módulo está diretamente relacionado com a rota. Logo faz sentido os componentes estarem dentro do módulo.

Trabalhar com módulos há ganhos significativos na inicialização da aplicação. É inimaginável uma aplicação Angular de médio porte sem módulos lazy load. E essa estrutura é coesa, mantém os grupos de interesse dentro de um mesmo local.

Core

O core module deve conter serviços singleton, componentes universais e outros recursos em que há uma instância única. Autenticação, header, interceptors são exemplos de componentes que terá apenas uma instância ativa para a aplicação e será utilizado praticamente por todos os modules.

Shared

O shared é onde todos os componentes compartilhados, pipes, filters e services devem ir. O shared pode ser importado em qualquer module. Assim esses itens serão reutilizados. O shared module deve ser independente do restante do aplicativo. Portanto, não deve ter referências de outro módulo.