No AngularJS, você foi capaz de especificar observadores para observar alterações nas variáveis de escopo usando a $watch
função de $scope
. Qual é o equivalente a observar alterações de variáveis (por exemplo, variáveis de componentes) no Angular?
213
Respostas:
No Angular 2, a detecção de alterações é automática ...
$scope.$watch()
e o$scope.$digest()
RIPInfelizmente, a seção Detecção de alterações do guia do desenvolvedor ainda não foi gravada (existe um espaço reservado na parte inferior da página Visão geral da arquitetura , na seção "O outro material").
Aqui está meu entendimento de como a detecção de alterações funciona:
setTimeout()
dentro de nossos componentes, em vez de algo como$timeout
... porquesetTimeout()
é o patch do macaco.ChangeDetectorRef
.) Esses detectores de alterações são criados quando o Angular cria componentes. Eles controlam o estado de todas as suas ligações, para verificação suja. Eles são, de certa forma, semelhantes ao automático$watches()
que o Angular 1 configuraria para{{}}
ligações de modelo.Diferentemente do Angular 1, o gráfico de detecção de alterações é uma árvore direcionada e não pode ter ciclos (isso torna o Angular 2 muito mais eficiente, como veremos abaixo).
onPush
estratégia de detecção de alterações em nenhum de seus componentes), todos os componentes da árvore serão examinados uma vez (TTL = 1) ... a partir do topo, em ordem de profundidade. (Bem, se você estiver no modo dev, a detecção de alterações será executada duas vezes (TTL = 2). Consulte ApplicationRef.tick () para obter mais informações sobre isso.) Realiza verificação suja em todas as suas ligações, usando esses objetos detectores de alterações.Se os dados do componente que você deseja assistir forem uma propriedade de entrada primitiva (String, boolean, number), você poderá implementar
ngOnChanges()
para ser notificado sobre alterações.Se a propriedade input for um tipo de referência (objeto, matriz, etc.), mas a referência não foi alterada (por exemplo, você adicionou um item a uma matriz existente), será necessário implementar
ngDoCheck()
(consulte esta resposta do SO para obter mais informações). nisto).Você deve alterar apenas as propriedades do componente e / ou propriedades dos componentes descendentes (devido à implementação de uma caminhada em árvore única - ou seja, fluxo de dados unidirecional). Aqui está um desentupidor que viola isso. Tubos com estado também podem levá-lo até aqui.
Outras referências para saber mais:
onPush
.fonte
host
documentação "Host Listeners" no documento API da DirectivaMetadata . Ele explica como ouvir eventos globais de dentro da zona Angular (para que a detecção de alterações seja acionada conforme desejado). Esta resposta tem um afunilador de trabalho.Esse comportamento agora faz parte do ciclo de vida do componente.
Um componente pode implementar o método ngOnChanges na interface OnChanges para obter acesso às alterações de entrada.
Exemplo:
fonte
Se, além da ligação bidirecional automática, você desejar chamar uma função quando um valor for alterado, poderá interromper a sintaxe do atalho de ligação bidirecional para a versão mais detalhada.
<input [(ngModel)]="yourVar"></input>
é uma abreviação de
<input [ngModel]="yourVar" (ngModelChange)="yourVar=$event"></input>
(veja, por exemplo, http://victorsavkin.com/post/119943127151/angular-2-template-syntax )
Você poderia fazer algo assim:
<input [(ngModel)]="yourVar" (ngModelChange)="changedExtraHandler($event)"></input>
fonte
Você pode usar
getter function
ouget accessor
atuar como relógio no angular 2.Veja a demonstração aqui .
fonte
Aqui está outra abordagem usando as funções getter e setter para o modelo.
fonte
(change)
manipulador (es) em cada um deles; Não quero adicionarget|sets
s a todas as propriedades do meu modelo; não ajudará a adicionar umget|set
parathis.object
;ngOnChanges()
detecta apenas alterações em@Input
s . Santo maná! O que eles fizeram conosco ??? Devolva-nos algum tipo de observação profunda!Se você deseja torná-lo vinculativo de duas vias, pode usar
[(yourVar)]
, mas é necessário implementar oyourVarChange
evento e chamá-lo sempre que sua variável for alterada.Algo assim para acompanhar a mudança do herói
e quando seu herói mudar, ligue
this.heroChange.emit(this.hero);
a
[(hero)]
ligação fará o resto por vocêveja o exemplo aqui:
http://plnkr.co/edit/efOGIJ0POh1XQeRZctSx?p=preview
fonte
Tente isto quando seu aplicativo ainda exige
$parse
,$eval
,$watch
como o comportamento em Angularhttps://github.com/vinayk406/angular-expression-parser
fonte
Isso não responde diretamente à pergunta, mas em várias ocasiões cheguei a essa questão do Stack Overflow para resolver algo que eu usaria $ watch nos angularJs. Acabei usando outra abordagem além da descrita nas respostas atuais e quero compartilhá-la caso alguém ache útil.
A técnica que eu uso para obter algo semelhante
$watch
é usar umBehaviorSubject
( mais sobre o tópico aqui ) em um serviço Angular e permitir que meus componentes se inscrevam nele para obter (observar) as alterações. Isso é semelhante ao a$watch
em angularJs, mas requer um pouco mais de configuração e entendimento.No meu componente:
No meu serviço
Aqui está uma demonstração no Stackblitz
fonte