En AngularJS pudo especificar observadores para observar cambios en las variables de alcance utilizando la $watch
función de $scope
. ¿Cuál es el equivalente de observar los cambios de las variables (en, por ejemplo, las variables componentes) en Angular?
213
Respuestas:
En Angular 2, la detección de cambios es automática ...
$scope.$watch()
y$scope.$digest()
RIPDesafortunadamente, la sección Detección de cambios de la guía de desarrollo aún no está escrita (hay un marcador de posición cerca de la parte inferior de la Descripción general de la arquitectura página , en la sección "Las otras cosas").
Aquí está mi comprensión de cómo funciona la detección de cambios:
setTimeout()
dentro de nuestros componentes en lugar de algo como$timeout
... porquesetTimeout()
es mono parcheado.ChangeDetectorRef
). Estos detectores de cambio se crean cuando Angular crea componentes. Realizan un seguimiento del estado de todas sus fijaciones, para realizar comprobaciones sucias. Estos son, en cierto sentido, similares a los automáticos$watches()
que Angular 1 configuraría para los{{}}
enlaces de plantillas.A diferencia de Angular 1, el gráfico de detección de cambios es un árbol dirigido y no puede tener ciclos (esto hace que Angular 2 sea mucho más eficiente, como veremos a continuación).
onPush
estrategia de detección de cambios en ninguno de sus componentes), cada componente del árbol se examina una vez (TTL = 1) ... desde arriba, en primer orden de profundidad. (Bueno, si está en modo dev, la detección de cambios se ejecuta dos veces (TTL = 2). Consulte ApplicationRef.tick () para obtener más información al respecto). Realiza una comprobación sucia de todos sus enlaces, utilizando esos objetos detectores de cambio.Si los datos del componente que desea ver son una propiedad de entrada primitiva (String, boolean, number), puede implementar
ngOnChanges()
para recibir notificaciones de cambios.Si la propiedad de entrada es un tipo de referencia (objeto, matriz, etc.), pero la referencia no cambió (por ejemplo, agregó un elemento a una matriz existente), deberá implementarla
ngDoCheck()
(consulte esta respuesta SO para obtener más información). en este).Solo debe cambiar las propiedades del componente y / o las propiedades de los componentes descendientes (debido a la implementación de un solo recorrido del árbol, es decir, el flujo de datos unidireccional). Aquí hay un saqueador que viola eso. Las tuberías con estado también pueden hacerte tropezar aquí.
Otras referencias para aprender más:
onPush
.fuente
host
"Host Listeners" en el documento de la API de GuidelinesMetadata . Explica cómo escuchar eventos globales desde el interior de la zona angular (por lo que la detección de cambios se activará como se desee). Esta respuesta tiene un golpeador que funciona.Este comportamiento ahora es parte del ciclo de vida del componente.
Un componente puede implementar el método ngOnChanges en la interfaz OnChanges para obtener acceso a los cambios de entrada.
Ejemplo:
fuente
Si, además del enlace bidireccional automático, desea llamar a una función cuando cambia un valor, puede romper la sintaxis de acceso directo del enlace bidireccional a la versión más detallada.
<input [(ngModel)]="yourVar"></input>
es una abreviatura de
<input [ngModel]="yourVar" (ngModelChange)="yourVar=$event"></input>
(véase, por ejemplo, http://victorsavkin.com/post/119943127151/angular-2-template-syntax )
Podrías hacer algo como esto:
<input [(ngModel)]="yourVar" (ngModelChange)="changedExtraHandler($event)"></input>
fuente
Puede usar
getter function
oget accessor
para actuar como reloj en angular 2.Ver demo aquí .
fuente
Aquí hay otro enfoque que utiliza las funciones getter y setter para el modelo.
fuente
(change)
controladores en cada uno de ellos; No quiero agregarget|sets
s a cada propiedad en mi modelo; no ayudará agregar unget|set
parathis.object
;ngOnChanges()
solo detecta cambios en@Input
s . Santo maná! ¿Qué nos hicieron? ¡Devuélvanos una observación profunda de algún tipo!Si desea hacer un enlace bidireccional, puede usarlo
[(yourVar)]
, pero debe implementar elyourVarChange
evento y llamarlo cada vez que cambie su variable.Algo como esto para rastrear el cambio de héroe
y luego cuando cambies tu héroe, llama
this.heroChange.emit(this.hero);
la
[(hero)]
encuadernación hará el resto por tiver ejemplo aquí:
http://plnkr.co/edit/efOGIJ0POh1XQeRZctSx?p=preview
fuente
Pruebe esto cuando su aplicación todavía exige
$parse
,$eval
,$watch
al igual que el comportamiento en Angularhttps://github.com/vinayk406/angular-expression-parser
fuente
Esto no responde la pregunta directamente, pero en diferentes ocasiones he llegado a esta pregunta de desbordamiento de pila para resolver algo que usaría $ watch en angularJs. Terminé usando un enfoque diferente al descrito en las respuestas actuales, y quiero compartirlo en caso de que alguien lo encuentre útil.
La técnica que uso para lograr algo similar
$watch
es usar unBehaviorSubject
( más sobre el tema aquí ) en un servicio angular y dejar que mis componentes se suscriban para obtener (ver) los cambios. Esto es similar a un$watch
en angularJs, pero requiere un poco más de configuración y comprensión.En mi componente:
En mi servicio
Aquí hay una demostración en Stackblitz
fuente