Angular 2 Как заставить Angular обнаруживать изменения, сделанные вне Angular?
Я пытаюсь создать простой пример проекта для проверки механизма обнаружения угловых изменений: я создаю чистый объект JavaScript в тегах сценария на главной странице индекса. он содержит следующее:
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 обнаружил изменение и обновил экран.
Мне это удалось: когда я вызываю Tryout.printme() из компонента (функция changeme() вызывает Tryout.printme()), Angular обнаруживает изменения и обновляет пользовательский интерфейс, что нормально. Кроме того, когда я изменяю внешний вид angular и вызываю consoleLogMe() из Angular, он записывает измененный текст и обновляет пользовательский интерфейс.
Я думаю, мне нужно выполнить Tryout.changeme() в той же зоне, в которой каким-то образом работает Angular. Есть идеи? У меня есть большой проект, который выполняется в чистом javascript/jquery, и теперь мне нужно медленно переписывать шаблоны руля в компоненты angular 2, не касаясь модели (пока). Для этого мне нужно заставить модель работать в той же зоне, что и угловая.
Если бы я хотел сделать что-то подобное в Angular 1, я бы просто использовал $scope.$ Apply, чтобы это работало.
Вот рисунок из примера:
1 ответ
Вы можете сделать это, экспортировав NgZone
внутри вашего углового приложения. Обычно вы должны делать все внутри 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
}
}
После угловой загрузки вы должны иметь zoneImpl
глобальная переменная. Вы можете использовать run
способ выкинуть Angular.
zoneImpl.run(() => window.app.name = "new name!")