page navigationend cambiar angular angular2-changedetection

navigationend - title angular 6



¿Cuál es el equivalente angular de un reloj AngularJS $? (8)

En AngularJS, pudo especificar observadores para observar los cambios en las variables de alcance utilizando la función $watch de $scope . ¿Cuál es el equivalente de observar cambios variables (en, por ejemplo, variables componentes) en Angular?


Aquí hay otro enfoque que utiliza las funciones getter y setter para el modelo.

@Component({ selector: ''input-language'', template: ` … <input type="text" placeholder="Language" [(ngModel)]="query" /> `, }) export class InputLanguageComponent { set query(value) { this._query = value; console.log(''query set to :'', value) } get query() { return this._query; } }


En Angular 2, la detección de cambios es automática ... $scope.$watch() y $scope.$digest() RIP

Desafortunadamente, 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 página Descripción general de la arquitectura , en la sección "Otras cosas").

Aquí está mi comprensión de cómo funciona la detección de cambios:

  • Zone.js "monkey parches the world": intercepta todas las API asincrónicas en el navegador (cuando se ejecuta Angular). Es por eso que podemos usar setTimeout() dentro de nuestros componentes en lugar de algo como $timeout ... porque setTimeout() tiene parches de mono.
  • Angular construye y mantiene un árbol de "detectores de cambio". Hay uno de estos detectores de cambio (clase) por componente / directiva. (Puede obtener acceso a este objeto inyectando ChangeDetectorRef ). Estos detectores de cambio se crean cuando Angular crea componentes. Realizan un seguimiento del estado de todas sus vinculaciones, para verificar sucias. Estos son, en cierto sentido, similares a los $watches() automáticos que Angular 1 configuraría para los enlaces de plantilla {{}} .
    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).
  • Cuando se dispara un evento (dentro de la zona angular), se ejecuta el código que escribimos (la devolución de llamada del controlador de eventos). Puede actualizar cualquier dato que desee: el modelo / estado de la aplicación compartida y / o el estado de vista del componente.
  • Después de eso, debido a los ganchos que Zone.js agregó, luego ejecuta el algoritmo de detección de cambios de Angular. De forma predeterminada (es decir, si no está utilizando la estrategia de detección de cambios onPush en ninguno de sus componentes), cada componente del árbol se examina una vez (TTL = 1) ... desde la parte superior, 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.
    • Los ganchos de ciclo de vida se llaman como parte de la detección de cambios.
      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á implementar ngDoCheck() (consulte esto responde por más sobre esto).
      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í.
  • Para cualquier cambio de enlace que se encuentre, los Componentes se actualizan y luego se actualiza el DOM. La detección de cambios ha finalizado.
  • El navegador nota que el DOM cambia y actualiza la pantalla.

Otras referencias para aprender más:


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:

import {Component, Input, OnChanges} from ''angular2/core''; @Component({ selector: ''hero-comp'', templateUrl: ''app/components/hero-comp/hero-comp.html'', styleUrls: [''app/components/hero-comp/hero-comp.css''], providers: [], directives: [], pipes: [], inputs:[''hero'', ''real''] }) export class HeroComp implements OnChanges{ @Input() hero:Hero; @Input() real:string; constructor() { } ngOnChanges(changes) { console.log(changes); } }


Esto no responde la pregunta directamente, pero en varias 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 un BehaviorSubject ( 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 algo más de configuración y comprensión.

En mi componente:

export class HelloComponent { name: string; // inject our service, which holds the object we want to watch. constructor(private helloService: HelloService){ // Here I am "watching" for changes by subscribing this.helloService.getGreeting().subscribe( greeting => { this.name = greeting.value; }); } }

En mi servicio

export class HelloService { private helloSubject = new BehaviorSubject<{value: string}>({value: ''hello''}); constructor(){} // similar to using $watch, in order to get updates of our object getGreeting(): Observable<{value:string}> { return this.helloSubject; } // Each time this method is called, each subscriber will receive the updated greeting. setGreeting(greeting: string) { this.helloSubject.next({value: greeting}); } }

Aquí hay una demostración en Stackblitz



Puede usar la getter function u get accessor para actuar como reloj en angular 2.

Ver demo here .

import {Component} from ''angular2/core''; @Component({ // Declare the tag name in index.html to where the component attaches selector: ''hello-world'', // Location of the template for this component template: ` <button (click)="OnPushArray1()">Push 1</button> <div> I''m array 1 {{ array1 | json }} </div> <button (click)="OnPushArray2()">Push 2</button> <div> I''m array 2 {{ array2 | json }} </div> I''m concatenated {{ concatenatedArray | json }} <div> I''m length of two arrays {{ arrayLength | json }} </div>` }) export class HelloWorld { array1: any[] = []; array2: any[] = []; get concatenatedArray(): any[] { return this.array1.concat(this.array2); } get arrayLength(): number { return this.concatenatedArray.length; } OnPushArray1() { this.array1.push(this.array1.length); } OnPushArray2() { this.array2.push(this.array2.length); } }


Si desea que sea vinculante en 2 direcciones, puede usar [(yourVar)] , pero debe implementar yourVarChange evento yourVarChange y llamarlo cada vez que cambie su variable.

Algo como esto para seguir el cambio de héroe

@Output() heroChange = new EventEmitter();

y luego, cuando cambien su héroe, llame a this.heroChange.emit(this.hero);

el enlace [(hero)] hará el resto por ti

ver ejemplo aquí:

http://plnkr.co/edit/efOGIJ0POh1XQeRZctSx?p=preview


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>