
Coleção com curadoria de trechos angulares úteis que você pode entender em 30 segundos ou menos.
Trechos iniciantes
Trechos intermediários
Trechos avançados
As enumes são ótimas, mas não são visíveis em modelos angulares por padrão. Com este pequeno truque, você pode torná -los acessíveis.
enum Animals {
DOG ,
CAT ,
DOLPHIN
}
@ Component ( {
...
} )
export class AppComponent {
animalsEnum : typeof Animals = Animals ;
}
Demoção interativa deste snippet | ⬆ Voltar ao topo | Tags: modelos de enums
Confira a folha de dicas angulares ou (versão alternativa) contendo muitas informações úteis condensadas em um só lugar.
Além disso, a lista de verificação angular contém é uma lista com curadoria de erros comuns cometidos ao desenvolver aplicações angulares.
https://malcoded.com/angular-theat-sheet/ ,https://angular.io/guide/Cheatsheet,
Demoção interativa deste snippet | ⬆ Voltar ao topo | Tags: folha de dicas
Depure o estado do componente no console do navegador executando:
ng . probe ( $0 ) . componentInstance
$0- é o nó DOM atualmente selecionado em ferramentas de dev ($1para o anterior e assim por diante).
Com o mecanismo de renderizador de hera:
ng . getComponent ( $0 ) https://blog.angularndepth.com/everything-you-need-to-nok-about-debugging-angular-pplications-d308ed8a51b4
Demoção interativa deste snippet | ⬆ Voltar ao topo | Tags: dicas de bom a saber
Se você estiver usando o ViewEncapsulation Value, que é diferente do padrão, pode ser assustador definir o valor manualmente para cada componente.
Felizmente, você pode configurá -lo globalmente ao inicializar seu aplicativo:
platformBrowserDynamic ( ) . bootstrapModule ( AppModule , [
{
// NOTE: Use ViewEncapsulation.None only if you know what you're doing.
defaultEncapsulation : ViewEncapsulation . None
}
] ) ;
Demoção interativa deste snippet | ⬆ Voltar ao topo | Tags: estilo de configuração
Para agir sobre swipes, panelas e pinhcentes, bem como os outros gestos móveis, você pode usar hammerjs com decorador HostListener ou uma ligação de eventos,
npm install hammerjs@ HostListener ( 'swiperight' )
public swiperight ( ) : void {
// Run code when a user swipes to the right
} Aqui estão amostras sobre como usar todas as ligações de eventos hammerjs , você também pode usar esses eventos com um HostListener :
<!-- pan events -->
< div (pan) =" logEvent($event) " > </ div >
< div (panstart) =" logEvent($event) " > </ div >
< div (panmove) =" logEvent($event) " > </ div >
< div (panend) =" logEvent($event) " > </ div >
< div (pancancel) =" logEvent($event) " > </ div >
< div (panleft) =" logEvent($event) " > </ div >
< div (panright) =" logEvent($event) " > </ div >
< div (panup) =" logEvent($event) " > </ div >
< div (pandown) =" logEvent($event) " > </ div >
<!-- pinch events -->
< div (pinch) =" logEvent($event) " > </ div >
< div (pinchstart) =" logEvent($event) " > </ div >
< div (pinchmove) =" logEvent($event) " > </ div >
< div (pinchend) =" logEvent($event) " > </ div >
< div (pinchcancel) =" logEvent($event) " > </ div >
< div (pinchin) =" logEvent($event) " > </ div >
< div (pinchout) =" logEvent($event) " > </ div >
<!-- press events -->
< div (press) =" logEvent($event) " > </ div >
< div (pressup) =" logEvent($event) " > </ div >
<!-- rotate events -->
< div (rotate) =" logEvent($event) " > </ div >
< div (rotatestart) =" logEvent($event) " > </ div >
< div (rotatemove) =" logEvent($event) " > </ div >
< div (rotateend) =" logEvent($event) " > </ div >
< div (rotatecancel) =" logEvent($event) " > </ div >
<!-- swipe events -->
< div (swipe) =" logEvent($event) " > </ div >
< div (swipeleft) =" logEvent($event) " > </ div >
< div (swiperight) =" logEvent($event) " > </ div >
< div (swipeup) =" logEvent($event) " > </ div >
< div (swipedown) =" logEvent($event) " > </ div >
<!-- tap event -->
< div (tap) =" logEvent($event) " > </ div > https://github.com/angular/angular/blob/master/packages/platform-browser/src/dom/events/hammer_gestures.ts,http://hammerjs.github.io/api/#hammer.manager,https://angular.io/api/platform-browser/HammerGestureConfig
Demoção interativa deste snippet | ⬆ Voltar ao topo | Tags: gestos de componentes de dicas de bom a saber
Você pode criar o próprio componente auxiliar e usá -lo em vez de *ngIf .
@ Component ( {
selector : 'loader' ,
template : `
<ng-content *ngIf="!loading else showLoader"></ng-content>
<ng-template #showLoader>? Wait 10 seconds!</ng-template>
`
} )
class LoaderComponent {
@ Input ( ) loading : boolean ;
}Para o exemplo de uso:
< loader [loading] =" isLoading " > ? ? ? </ loader >Observe que o conteúdo será avaliado ansiosamente, por exemplo, no trecho abaixo,
destroy-the-worldserá criado antes que o carregamento seja iniciado:
< loader [loading] =" isLoading " > < destroy-the-world > </ destroy-the-world > </ loader > https://medium.com/claritydesignsystem/ng-content-the-hden-docs-96a29d70d11b.https://blog.angularindepth.com/https-medium-com-thomasbleson-animated-ghostss-bfc0451fba
Demoção interativa deste snippet | ⬆ Voltar ao topo | Tags: dicas de modelos de componentes bons para saber
Com ng-content você pode passar qualquer elemento para um componente. Isso simplifica a criação de componentes reutilizáveis.
@ Component ( {
selector : 'wrapper' ,
template : `
<div class="wrapper">
<ng-content></ng-content>
</div>
` ,
} )
export class Wrapper { } < wrapper >
< h1 > Hello World! </ h1 >
</ wrapper > https://medium.com/p/96a29d70d11b
Demoção interativa deste snippet | ⬆ Voltar ao topo | Tags: componentes de dicas de bom a saber
*ngIf também suporta a instrução else .
< div *ngIf =" isLoading; else notLoading " > loading... </ div >
< ng-template #notLoading > not loading </ ng-template >
Demoção interativa deste snippet | ⬆ Voltar ao topo | Tags: modelos NGIF
Navegue com os parâmetros da matriz:
O roteador navegará para /first;name=foo/details
< a [routerLink] =" ['/', 'first', {name: 'foo'}, 'details'] " >
link with params
</ a > https://stackblitz.com/edit/angular-xvy5pd
Demoção interativa deste snippet | ⬆ Voltar ao topo | Tags: roteamento
Em certos casos, as propriedades @Input e @Output podem ser nomeadas de maneira diferente das entradas e saídas reais.
< div
pagination
paginationShowFirst =" true "
(paginationPageChanged) =" onPageChanged($event) " >
</ div > @ Directive ( { selector : '[pagination]' } )
class PaginationComponent {
@ Input ( 'paginationShowFirst' )
showFirst : boolean = true ;
@ Output ( 'paginationPageChanged' )
pageChanged = new EventEmitter ( ) ;
}NOTA: Use isso com sabedoria, consulte o StyleGuide Recometedation
https://angular.io/guide/styleguide#style-05-13
Demoção interativa deste snippet | ⬆ Voltar ao topo | Tags: modelos de componentes
O operador de navegação seguro ajuda a prevenir exceções de referência nula em expressões de modelo de componentes. Ele retorna o valor da propriedade do objeto se existir ou nulo caso contrário.
< p > I will work even if student is null or undefined: {{student?.name}} </ p >{{a?.b?.c}} Embaixo será compilado.
(_co.a == null)? null: ((_co.a.b == null)? null: _co.a.b.c));Angular/Angular#791
Demoção interativa deste snippet | ⬆ Voltar ao topo | Tags: dicas de manuseio de propriedades de objeto bom saber
Para evitar as operações caras, podemos ajudar a Angular a rastrear quais itens adicionados ou removidos, ou seja, personalize o algoritmo de rastreamento padrão, fornecendo uma opção Trackby para o NGFOROF.
Para que você possa fornecer sua função de trackby personalizada que retorneá identificador exclusivo para cada item iterado. Por exemplo, algum valor chave do item. Se esse valor de chave corresponder ao anterior, o Angular não detectará alterações.
O trackby leva uma função que possui Índice e Item Args.
@ Component ( {
selector : 'my-app' ,
template : `
<ul>
<li *ngFor="let item of items; trackBy: trackByFn">{{item.id}}</li>
</ul>
`
} )
export class AppComponent {
trackByFn ( index , item ) {
return item . id ;
}
}Se o trackby for fornecido, as faixas angulares mudam pelo valor de retorno da função.
Agora, quando você muda a coleção, o Angular pode rastrear quais itens foram adicionados ou removidos de acordo com o identificador exclusivo e criar/destruir apenas itens alterados.
https://angular.io/api/common/ngforof.https://angular.io/api/core/trackbyfunction
Demoção interativa deste snippet | ⬆ Voltar ao topo | Tags: dicas de bom a saber desempenho componentes
Sob o Hood Angular compila diretrizes estruturais em elementos NG-Template, por exemplo:
<!-- This -->
< div *ngFor =" let item of [1,2,3] " >
<!-- Get expanded into this -->
< ng-template ngFor [ngForOf] =" [1,2,3] " let-item =" $implicit " > </ ng-template >O valor aprovado para a diretiva *ngfor é escrito usando o microssyntax. Você pode aprender sobre isso nos documentos.
Confira também uma ferramenta interativa que mostra a expansão de Alexey Zuev
https://angular.io/guide/structural-directives#microsyntax ,https://alexzuzuza.github.io/ng-structural-directive-expander/.https://angular.io/guide/structural-directives#inside
Demoção interativa deste snippet | ⬆ Voltar ao topo | Tags: Microssyntax Diretiva estrutural da dica
Às vezes, precisamos trabalhar com cada controle é um formulário. Aqui está como isso pode ser feito:
function flattenControls ( form : AbstractControl ) : AbstractControl [ ] {
let extracted : AbstractControl [ ] = [ form ] ;
if ( form instanceof FormArray || form instanceof FormGroup ) {
const children = Object . values ( form . controls ) . map ( flattenControls ) ;
extracted = extracted . concat ( ... children ) ;
}
return extracted ;
}Para exemplos de uso:
// returns all dirty abstract controls
flattenControls ( form ) . filter ( ( control ) => control . dirty ) ;
// mark all controls as touched
flattenControls ( form ) . forEach ( ( control ) =>
control . markAsTouched ( { onlySelf : true } ) ) ; https://angular.io/guide/reactive-forms
Demoção interativa deste snippet | ⬆ Voltar ao topo | Tags: formas reativas dicas boas para saber
É realmente fácil adicionar atalhos de teclado no modelo:
< textarea (keydown.ctrl.enter) =" doSomething() " > </ textarea > < input (keydown.enter) =" ... " >
< input (keydown.a) =" ... " >
< input (keydown.esc) =" ... " >
< input (keydown.shift.esc) =" ... " >
< input (keydown.control) =" ... " >
< input (keydown.alt) =" ... " >
< input (keydown.meta) =" ... " >
< input (keydown.9) =" ... " >
< input (keydown.tab) =" ... " >
< input (keydown.backspace) =" ... " >
< input (keydown.arrowup) =" ... " >
< input (keydown.shift.arrowdown) =" ... " >
< input (keydown.shift.control.z) =" ... " >
< input (keydown.f4) =" ... " > https://alligator.io/angular/binding-keyup-keydown-events
Demoção interativa deste snippet | ⬆ Voltar ao topo | Tags: dicas boas para saber
Cada componente angular renderizado é envolvido em um elemento host (que é o mesmo que o seletor do componente).
É possível vincular propriedades e atributos do elemento host usando decoradores @hostbinding, por exemplo
import { Component , HostBinding } from '@angular/core' ;
@ Component ( {
selector : 'my-app' ,
template : `
<div>Use the input below to select host background-color:</div>
<input type="color" [(ngModel)]="color">
` ,
styles : [
`:host { display: block; height: 100px; }`
]
} )
export class AppComponent {
@ HostBinding ( 'style.background' ) color = '#ff9900' ;
}
Demoção interativa deste snippet | ⬆ Voltar ao topo | Tags: componentes
Geralmente obtemos uma instância de serviço de acordo com todo o aplicativo. Também é possível criar uma instância de serviço por componente ou diretiva.
@ Component ( {
selector : 'provide' ,
template : '<ng-content></ng-content>' ,
providers : [ Service ]
} )
export class ProvideComponent { } @ Directive ( {
selector : '[provide]' ,
providers : [ Service ]
} )
export class ProvideDirective { } https://angular.io/guide/hierchical-dependency-injection#component-level-injects ,https://stackblitz.com/edit/angular-cdk-hppy-animals
Demoção interativa deste snippet | ⬆ Voltar ao topo | Tags: dicas componentes de dependência injeção de dependência
É possível adicionar ouvintes de eventos globais em seus componentes/diretrizes com HostListener . Angular cuidará de cancelar a inscrição assim que sua diretiva for destruída.
@ Directive ( {
selector : '[rightClicker]'
} )
export class ShortcutsDirective {
@ HostListener ( 'window:keydown.ArrowRight' )
doImportantThings ( ) {
console . log ( 'You pressed right' ) ;
}
}Você pode ter várias ligações:
@ HostListener ( 'window:keydown.ArrowRight' )
@ HostListener ( 'window:keydown.PageDown' )
next ( ) {
console . log ( 'Next' )
}Você também pode passar os parâmetros:
@ HostListener ( 'window:keydown.ArrowRight' , '$event.target' )
next ( target ) {
console . log ( 'Pressed right on this element: ' + target )
}
Demoção interativa deste snippet | ⬆ Voltar ao topo | Tags: componentes de eventos
Às vezes, você precisa ter acesso ao document global.
Para simplificar o teste de unidade, o Angular o fornece por meio de injeção de dependência:
import { DOCUMENT } from '@angular/common' ;
import { Inject } from '@angular/core' ;
@ Component ( {
selector : 'my-app' ,
template : `<h1>Edit me </h1>`
} )
export class AppComponent {
constructor ( @ Inject ( DOCUMENT ) private document : Document ) {
// Word with document.location, or other things here....
}
} https://angular.io/api/common/document
Demoção interativa deste snippet | ⬆ Voltar ao topo | Tags: injeção de dependência
Aqui está a maneira de notificar o usuário que existem campos com valores não válidos.
markFieldsAsTouched FormGroup ou FormArray como argumento.
function markFieldsAsTouched ( form : AbstractControl ) : void {
form . markAsTouched ( { onlySelf : true } ) ;
if ( form instanceof FormArray || form instanceof FormGroup ) {
Object . values ( form . controls ) . forEach ( markFieldsAsTouched ) ;
}
}É muito útil verificar o método mais geral acessando todos os controles de formulário aninhados da Thekiba para trabalhar com controles.
https://angular.io/guide/reactive-forms
Demoção interativa deste snippet | ⬆ Voltar ao topo | Tags: formas reativas dicas de validação boas para saber
EventEmitters usados para @Output são apenas observáveis com um método emit.
Isso significa que você pode apenas usar a instância Observable , por exemplo, podemos conectar alterações de valor de formulário diretamente:
readonly checkbox = new FormControl ( ) ;
@ Output ( ) readonly change = this . checkbox . valueChanges ;
Demoção interativa deste snippet | ⬆ Voltar ao topo | Tags: saídas da dica
É possível pegar um modelo como @Input para um componente personalizar a renderização
@ Component ( {
template : `
<nav>
<ng-container *ngTemplateOutlet="template"></ng-container>
</nav>
` ,
} )
export class SiteMenuComponent {
@ Input ( ) template : TemplateRef < any > ;
} < site-menu [template] =" menu1 " > </ site-menu >
< ng-template #menu1 >
< div > < a href =" # " > item1 </ a > </ div >
< div > < a href =" # " > item2 </ a > </ div >
</ ng-template >NOTA:
ng-contentdeve ser usado na maioria dos casos e é mais simples e mais declarativo. Use apenas essa abordagem se precisar de flexibilidade extra que não possa ser alcançada com o conteúdo NG.
https://blog.angular-university.io/angular-ng-template-ng-container-ngtemplateoutlet
Demoção interativa deste snippet | ⬆ Voltar ao topo | Tags: modelo
Por padrão, tiras angulares todos os espaços em branco em modelos para salvar bytes. Geralmente é seguro.
Para casos raros, quando você precisa preservar os espaços, você pode usar o atributo ngPreserveWhitespaces especiais:
< div ngPreserveWhitespaces >
(___()'`;
/, /`
jgs \"--\
</ div >Você também pode usar a opção PreserveWhitaSpaces em um componente.
https://twitter.com/mgechev/status/1108913389277839360
Demoção interativa deste snippet | ⬆ Voltar ao topo | Tags: dica
Embora a melhor maneira de reutilizar seu código seja criar um componente, também é possível fazê -lo em um modelo.
Para fazer isso, você pode usar ng-template junto com a diretiva *ngTemplateOutlet .
< p >
< ng-container *ngTemplateOutlet =" fancyGreeting " > </ ng-container >
</ p >
< button >
< ng-container *ngTemplateOutlet =" fancyGreeting " > </ ng-container >
</ button >
< ng-template #fancyGreeting >
Hello < b > {{name}}! </ b >
</ ng-template > https://angular.io/api/common/ngtemplateoutlet.https://angular.io/guide/structural-directives#the-ng-template
Demoção interativa deste snippet | ⬆ Voltar ao topo | Tags: modelos
Se você precisar de um pipe personalizado, antes de criar um, considere verificar o pacote NGX Pipes, que tem mais de 70 tubos personalizados.
Aqui estão alguns exemplos:
< p > {{ date | timeAgo }} </ p >
<!-- Output: "last week" -->
< p > {{ 'foo bar' | ucfirst }} </ p >
<!-- Output: "Foo bar" -->
< p > 3 {{ 'Painting' | makePluralString: 3 }} </ p >
<!-- Output: "3 Paintings" -->
< p > {{ [1, 2, 3, 1, 2, 3] | max }} </ p >
<!-- Output: "3" --> https://github.com/danrevah/ngx-pipes
Demoção interativa deste snippet | ⬆ Voltar ao topo | Tags: biblioteca de tubos de ponta
Você pode usar ligações avançadas de propriedades para definir valores de estilo específicos com base nos valores de propriedades do componente:
< p [style.background-color] =" 'green' " >
I am in green background
</ p >
< p [style.font-size.px] =" isImportant ? '30' : '16' " >
May be important text.
</ p > <!-- Width in pixels -->
< div [style.width.px] =" pxWidth " > </ div >
<!-- Font size in percentage relative to the parent -->
< div [style.font-size.%] =" percentageSize " > ... </ div >
<!-- Height relative to the viewport height -->
< div [style.height.vh] =" vwHeight " > </ div >
Demoção interativa deste snippet | ⬆ Voltar ao topo | Tags: estilos
Semelhante à forma como você pode se ligar bidirecional [(ngModel)] você pode se ligar à propriedade de ligação bidirecional em um componente, por exemplo [(value)] . Para fazer isso, use a nomeação de entrada/saída apropriada:
@ Component ( {
selector : 'super-input' ,
template : `...` ,
} )
export class AppComponent {
@ Input ( ) value : string ;
@ Output ( ) valueChange = new EventEmitter < string > ( ) ;
}Então você pode usá -lo como:
< super-input [(value)] =" value " > </ super-input >
Demoção interativa deste snippet | ⬆ Voltar ao topo | Tags: encadernação da dica
É possível executar a tarefa assíncrona antes do início do aplicativo, fornecendo uma função que retornando promessa usando o token APP_INITIALIZER .
@ NgModule ( {
providers : [
{
provide : APP_INITIALIZER ,
useValue : functionReturningPromise
multi : true
} ,
} )
export class AppModule { }
https://hackernoon.com/hook-into-angular-initialization-process-add41a6b7e ,https://angular.io/api/core/app_initializer
Demoção interativa deste snippet | ⬆ Voltar ao topo | Tags: dica
Para fins de teste, você pode querer injetar o objeto window.location em seu componente. Você pode conseguir isso com o mecanismo personalizado InjectionToken fornecido pelo Angular.
export const LOCATION_TOKEN = new InjectionToken < Location > ( 'Window location object' ) ;
@ NgModule ( {
providers : [
{ provide : LOCATION_TOKEN , useValue : window . location }
]
} )
export class SharedModule { }
//...
@ Component ( {
} )
export class AppComponent {
constructor (
@ Inject ( LOCATION_TOKEN ) public location : Location
) { }
} https://itnext.io/testing-browser-window-location-in-angular-application-e4e8388508ff ,https://angular.io/guide/dependency-injeject
Demoção interativa deste snippet | ⬆ Voltar ao topo | Tags: teste de injeção de dependência
É possível usar @ViewChild (também @ViewChildren e @ContentChild/Children ) para consultar componentes de diferentes tipos usando injeção de dependência.
No exemplo abaixo, podemos usar @ViewChildren(Base) para obter instâncias de Foo e Bar .
abstract class Base { }
@ Component ( {
selector : 'foo' ,
providers : [ { provide : Base , useExisting : Foo } ]
} )
class Foo extends Base { }
@ Component ( {
selector : 'bar' ,
providers : [ { provide : Base , useExisting : Bar } ]
} )
class Bar extends Base { }
// Now we can require both types of components using Base.
@ Component ( { template : `<foo></foo><bar></bar>` } )
class AppComponent {
@ ViewChildren ( Base ) components : QueryList < Base > ;
} https://www.youtube.com/watch?v=prrgo6f0cjs
Demoção interativa deste snippet | ⬆ Voltar ao topo | Tags: dicas de bom a saber componentes de dependência injeção de dependência
O Angular nos permite controlar a maneira como a pré -carga do módulo é tratada.
Existem 2 estratégias fornecidas por @angular/roteador : PreloadAllModules e NoPreloading . Este último permitiu por padrão, apenas pré -carregando módulos preguiçosos sob demanda.
Podemos substituir esse comportamento fornecendo estratégia de pré -carregamento personalizada: no exemplo abaixo, pré -carregamos todos os módulos incluídos se a conexão for boa.
import { Observable , of } from 'rxjs' ;
export class CustomPreloading implements PreloadingStrategy {
public preload ( route : Route , load : ( ) => Observable < any > ) : Observable < any > {
return preloadingConnection ( ) ? load ( ) : of ( null ) ;
}
}
const routing : ModuleWithProviders = RouterModule . forRoot ( routes , {
preloadingStrategy : CustomPreloading
} ) ;Observe que o exemplo acima não seria muito eficiente para aplicativos maiores, pois pré -carregará todos os módulos.
https://angular.io/api/router/preloadingstrategy ,https://vsavkin.com/angular-ruter-preloading-modules-ba3c75e424cb.https://medium.com/@adrianfaci u/personalidade de pré-)-)-FLOME-para-angular-Modules-B3B5C873681a, https: //coryrylan.com/blog/custom-preloading-andlazy-loading-trategies-with--angular
Demoção interativa deste snippet | ⬆ Voltar ao topo | Tags: roteador
É possível usar tags SVG em seu componente angular, para criar belos gráficos e visualizações. Há 3 coisas que você precisa saber:
attr < circle [attr.cx] =" x " [attr.cy] =" y " > </ circle >// Not: < child-component > </ child-component >
< g child-component > </ g > @ Component ( { selector : '[child-component]' } )@ Component ( {
selector : '[child-component]' ,
template : `<svg:circle></svg:circle>`
} )
Demoção interativa deste snippet | ⬆ Voltar ao topo | Tags: TIP SVG