javascript typescript angular angular2-changedetection

javascript - Angular 2 ¿Cómo obtener Angular para detectar cambios realizados fuera de Angular?



typescript angular2-changedetection (1)

Estoy tratando de crear un proyecto de ejemplo simple para probar el mecanismo de detección de cambio angular 2: creo un objeto javascript puro en etiquetas de script en la página de índice principal. Contiene lo siguiente:

var Tryout = {}; Tryout.text = "Original text here"; Tryout.printme = function(){ console.log(Tryout.text); } Tryout.changeme = function(){ Tryout.text = "Change was made"; }

Una función para iniciar sesión en la consola y otra para cambiar la propiedad de texto.

Ahora en Angular 2 el código se ve así:

import {Component} from "angular2/core" @Component({ selector: ''my-app'', template: ` <h1>{{TryoutRef.text}}</h1> <input type="text" [(ngModel)]="TryoutRef.text"> <button (click)="consoleLogMe()">Console Log</button> <button (click)="changeMe()">Change me inside</button> ` }) export class MyApp{ TryoutRef:any = Tryout; constructor(){ } changeMe(){ this.TryoutRef.changeme(); } consoleLogMe(){ console.log(this.TryoutRef.text); } } declare var Tryout:string;

Lo que estoy tratando de hacer es esto: cuando llamo a la función Tryout.printme () normalmente con un clic (Completamente fuera del ángulo), quiero que Angular detecte el cambio y actualice la pantalla.

Logré este punto: cuando llamo a Tryout.printme () desde el componente (la función changeme () llama a Tryout.printme ()), Angular detecta el cambio y actualiza la interfaz de usuario que está bien. Además, cuando cambio desde fuera angular y llamo consoleLogMe () desde Angular, está registrando el texto modificado y actualiza la interfaz de usuario.

Supongo que necesito ejecutar Tryout.changeme () en la misma zona que Angular está ejecutando de alguna manera. ¿Algunas ideas? Tengo un gran proyecto que se realiza en javascript / jquery puro, y ahora necesito volver a escribir las plantillas del manillar en los componentes angulares2 sin tocar el modelo (todavía). Para eso necesito forzar al modelo a ejecutarse en la misma zona que angular.

Si quisiera hacer algo como esto en Angular 1, solo tendría $ alcance. $ Aplicaría que funcionaría.

Aquí hay un gif del ejemplo:


Puedes hacerlo exportando NgZone dentro de tu aplicación Angular. Por lo general, debe hacer todas las cosas dentro de Angular, pero si realmente desea ejecutar su lógica desde Angular, debe obtener la zone correcta, como ha dicho.

Este truco consiste en abusar de la inyección de dependencia de Angular y enganchar la zone inyectada en el objeto de la window , como muestra este problema . Declarar una dependencia en NgZone y asignarla a window.zoneImpl para exportar.

//our root app component import {Component, NgZone} from ''angular2/core'' @Component({ selector: ''my-app'', template: ` <div> <h2>Hello {{name}}</h2> </div> `, }) export class App { constructor(zone: NgZone) { this.name = ''Angular2'' window.app = this window.zoneImpl = zone } }

Después del arranque angular, debe tener una variable global zoneImpl . Puede utilizar el método de run para iniciar Angular.

zoneImpl.run(() => window.app.name = "new name!")

Demo en vivo.