O que é Angular detecção de mudanças e estratégias de detecção de mudanças
Angular Detecção de Alterações é um mecanismo para detectar alterações de dados em qualquer componente do seu aplicativo. Saiba como funciona e como ativá-lo com Ignite UI.
Um dos maiores pontos fortes do Angular é sua capacidade de detectar e atualizar facilmente as alterações em um aplicativo, enquanto renderiza automaticamente o estado atualizado na tela. Para ajudá-lo a entender melhor o hype em torno da detecção de alterações Angular, como a detecção de alterações funciona em Angular Bibliotecas de Componentes e as estratégias que os desenvolvedores geralmente implementam, fornecerei alguns exemplos Angular de detecção de alterações e abordarei os seguintes tópicos neste artigo:
O que é detecção de alterações no Angular?
Angular Detecção de Alterações é um mecanismo para detectar quando os dados são alterados em qualquer componente do seu aplicativo e renderiza novamente a exibição, para que ele exiba os valores ou objetos atualizados para os usuários finais imediatamente. Dessa forma, a estrutura garante que a interface do usuário esteja sincronizada com o estado interno do software – o componente e a exibição estão sempre sincronizados.
As mudanças ocorrem em diferentes ocasiões e derivam de diferentes eventos:
- Dados recebidos de solicitações de rede ou eventos de componentes
- Cliques do mouse, rolagem, mouseover, navegação por teclado
- AJAX calls
- Uso de funções de temporizador JavaScript, como setTimeOut, SetInterval
Como funciona a detecção de alterações no Angular?
Por padrão, Angular executa a detecção de alterações no Angular Grid + em todos os outros componentes (de cima para baixo) sempre que algo aciona uma alteração em seu aplicativo – seja um evento do usuário ou dados recebidos de uma solicitação de rede, como mencionei anteriormente. Para detectar e atualizar o DOM com dados alterados, a estrutura fornece seu próprio detector de alterações para cada componente. O detector de alterações lê a associação em um modelo e reflete os dados atualizados para a exibição, garantindo que o modelo de dados e o DOM estejam sincronizados.
Por exemplo, talvez você queira atualizar uma associação de componente que atualiza respectivamente o modelo de dados. O detector de alterações Angular detecta a alteração acionada e executa a detecção de alterações para verificar todos os componentes na árvore de componentes de cima para baixo. Dessa forma, ele verifica se o modelo correspondente foi alterado. E no caso de um novo valor, ele atualiza instantaneamente o DOM.
Imagine que um usuário clica em um botão Alterar endereço ao preencher um formulário online. Essa ação aciona automaticamente a detecção de alterações para cada Exibição na árvore de detecção de alterações. O detector de alterações Angular coleta todas as exibições que devem ser verificadas quanto a alterações e atualiza o valor da propriedade firstname do usuário que solicitou essa alteração em primeiro lugar.
Angular Change Detection Strategies
Como desenvolvedores, sabemos que nossos aplicativos Angular devem atender a vários requisitos para funcionar perfeitamente, ter alto desempenho e oferecer uma ótima experiência do usuário. Devemos construí-los para serem interativos, responsivos e, acima de tudo, atualizados, o que significa que o estado do modelo interno deve sempre sincronizar com a exibição. Assim, sempre que queremos otimizar seu desempenho, adotamos estratégias de detecção de alterações no Angular, que pode atualizar o DOM sempre que os dados forem alterados.
Há duas estratégias Angular de detecção de alterações que a estrutura fornece:
- Estratégia padrão
- OnPush strategy
Angular Estratégia de detecção de alterações padrão
Se Angular ChangeDetector estiver definido como padrão, para qualquer alteração em qualquer propriedade do modelo, Angular executará a detecção de alterações atravessando uma árvore de componentes para atualizar o DOM. Cada componente possui um detector de alterações que é criado quando o aplicativo é iniciado.
A classe ChangeDetectorRef fornece alguns métodos internos que podemos usar para manipular a árvore de detecção de alterações:
- markForCheck() — marca os componentes como foram alterados, para que possam ser verificados novamente para uma atualização
- detach() — exclui a visualização da árvore de detecção de alterações, o que significa que nenhuma verificação será acionada até que a visualização seja reanexada novamente
- detectChanges() — verifica a visualização e seus componentes filhos
- checkNoChanges() — verifica a view e seus filhos e ele lançará um erro se algumas alterações forem detectadas
- reattach() — reanexa uma visualização que foi desanexada anteriormente para que novas alterações possam ser detectadas
Angular OnPush Change Detection Strategy
Se Angular ChangeDetector estiver definido como onPush, Angular executará o detector de alterações somente quando uma nova referência estiver sendo passada para o componente. Se o observável for passado para onPush, Angular ChangeDetector deverá ser chamado manualmente para atualizar o DOM.
@Component({ selector: 'app-card', templateUrl: './card.component.html', changeDetection: ChangeDetectionStrategy.OnPush, styleUrls: ['./card.component.scss'] }) export class CardComponent { … } }
Benefits of onPush change detection
Verificações desnecessárias em componentes filhos não são executadas se o elemento pai estiver atualizando valores que não são passados como propriedades @Input(), fornecendo uma renderização significativamente mais rápida dos componentes.
Usando a detecção de alterações com Ignite UI for Angular
Vamos criar um exemplo simples exibindo uma lista com itens para compras usando Ignite UI for Angular. Vamos ter um componente de lista de compras e uma entrada onde podemos adicionar novos itens à lista.
import { Component } from '@angular/core'; import { BehaviorSubject } from 'rxjs'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class AppComponent { items = new BehaviorSubject(['Apples', 'Tomatoes', 'Potatoes']); constructor() { } addNewItem(item) { this.items.next([...this.items, item]); } }
No app.component.ts vamos declarar um BehaviorSubject com alguns valores padrão e um método que vai adicionar um novo item à lista.
<input #newItem type="text" placeholder="Add new item"> <button (click)="addNewItem(newItem.value)">Add Item</button> <shopping-items [data]="items"></shopping-items>
Vamos criar um componente filho de itens de compras que exibirá os itens usando o componente igx-list.
<h5 class="h5">Shopping List</h5> <igx-list class="list" *ngFor="let item of shoppingItems"> <igx-list-item class="list-item"> <span>{{item}}</span> </igx-list-item> </igx-list>
import { ChangeDetectorRef, Component, Input } from '@angular/core'; import { Observable } from 'rxjs'; @Component({ selector: 'shopping-items', templateUrl: './child.component.html', styleUrls: ['./child.component.css'] }) export class ShoppingList { @Input() data: Observable<any>; shoppingItems: string[] = []; constructor(private changeDetector: ChangeDetectorRef) { } ngOnInit() { this.data.subscribe(item => { this.shoppingItems = [...this.shoppingItems, ...item]; this.changeDetector.markForCheck(); }); } }
Se não usarmos o método markForCheck() aqui de ChangeDetectorRef, Angular se recusará a executar a detecção de alterações. É por isso que precisamos fazer isso manualmente. Com esse método, dizemos a Angular para executar a detecção de alterações quando uma entrada específica aparecer quando mutada.
Conclusão
Quanto maior o projeto, mais lentidão ele pode ter. Angular A detecção de alterações é uma técnica que pode ajudar a aumentar a eficiência do aplicativo. Portanto, para projetos maiores, seria melhor usar ChangeDetectionStrategy.OnPush, pois ele economiza desempenho.
