Подтвердить что ты не робот

Angular 2 Как получить Angular для обнаружения изменений вне Angular?

Я пытаюсь создать простой пример проекта для проверки механизма обнаружения изменений angular 2: я создаю чистый объект javascript в тегах script на главной странице индекса. он содержит следующее:

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

Одна функция для консольного журнала, а другая - для изменения свойства текста.

Теперь в angular 2 код выглядит следующим образом:

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;

То, что я пытаюсь сделать, это: Когда я вызываю функцию Tryout.printme() обычно с помощью onclick (полностью вне angular), я хочу, чтобы angular обнаружил изменение и обновил экран.

Мне это удалось: Когда я вызываю Tryout.printme() из компонента (функция changeme() вызывает Tryout.printme()), angular обнаруживает изменение и обновляет пользовательский интерфейс, который является прекрасным. Кроме того, когда я переключаюсь извне angular, и я вызываю consoleLogMe() из angular, он регистрирует измененный текст и обновляет пользовательский интерфейс.

Мне кажется, мне нужно выполнить Tryout.changeme() в той же самой зоне, что angular работает как-то. Есть идеи? У меня большой проект, который выполняется в чистом javascript/jquery, и теперь мне медленно нужно переписать шаблоны руля на компоненты angular2, не касаясь модели (пока). Для этого мне нужно заставить модель выполнить в той же зоне, что и angular.

Если бы я хотел сделать что-то вроде этого в angular 1, я бы просто использовал $scope. $apply, это сработает.

Вот пример из примера:

введите описание изображения здесь

4b9b3361

Ответ 1

Вы можете сделать это, экспортировав NgZone в ваше приложение Angular. Как правило, вы должны делать все в Angular, но если вы действительно хотите выполнить свою логику из Angular, вам нужно получить право zone, как вы сказали.

Этот трюк злоупотребляет инъекцией зависимостей Angular и подключает введенный zone объект window, как показано эта проблема. Объявление зависимости от NgZone и назначение его window.zoneImpl для экспорта.

//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
  }
}

После Angular начальной загрузки вы должны иметь глобальную переменную zoneImpl. Вы можете использовать метод run, чтобы отключить Angular.

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

демо-версия.