Angular 2 如何让 Angular 检测在 Angular 之外所做的更改?
Angular 2 How to get Angular to detect changes made outside Angular?
我正在尝试创建一个简单的示例项目来测试 angular 2 更改检测机制:我在主索引页面的脚本标记中创建了一个纯 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;
我想做的是:
当我通常使用 onclick 调用函数 Tryout.printme() 时(完全在 angular 之外)我希望 angular 检测更改并更新屏幕。
我成功做到了这一点:当我从组件调用 Tryout.printme() 时(changeme() 函数正在调用 Tryout.printme()),Angular 检测到变化并且更新 UI 这很好。此外,当我从 angular 外部更改并从 Angular 调用 consoleLogMe() 时,它会记录更改的文本并更新 UI。
我想我需要在 Angular 以某种方式与 运行 相同的区域中执行 Tryout.changeme()。有任何想法吗?我有一个纯 javascript/jquery 完成的大项目,现在我需要慢慢地将车把模板重写为 angular2 个组件,而无需触及模型(还)。为此,我需要强制模型在与 angular.
相同的区域中执行
如果我想在 Angular 1 中做这样的事情,我只要 $scope.$apply 就可以了。
这是示例中的 gif:
您可以通过在 Angular 应用程序中导出 NgZone
来完成此操作。
通常,你应该在 Angular 里面做所有的事情,但是如果你真的想在 Angular 之外执行你的逻辑,你需要得到正确的 zone
,正如你所说的。
这个技巧滥用了 Angular 的依赖注入,并将注入的 zone
挂接到 window
对象上,如 this issue 所示。声明对 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!")
我正在尝试创建一个简单的示例项目来测试 angular 2 更改检测机制:我在主索引页面的脚本标记中创建了一个纯 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;
我想做的是: 当我通常使用 onclick 调用函数 Tryout.printme() 时(完全在 angular 之外)我希望 angular 检测更改并更新屏幕。
我成功做到了这一点:当我从组件调用 Tryout.printme() 时(changeme() 函数正在调用 Tryout.printme()),Angular 检测到变化并且更新 UI 这很好。此外,当我从 angular 外部更改并从 Angular 调用 consoleLogMe() 时,它会记录更改的文本并更新 UI。
我想我需要在 Angular 以某种方式与 运行 相同的区域中执行 Tryout.changeme()。有任何想法吗?我有一个纯 javascript/jquery 完成的大项目,现在我需要慢慢地将车把模板重写为 angular2 个组件,而无需触及模型(还)。为此,我需要强制模型在与 angular.
相同的区域中执行如果我想在 Angular 1 中做这样的事情,我只要 $scope.$apply 就可以了。
这是示例中的 gif:
您可以通过在 Angular 应用程序中导出 NgZone
来完成此操作。
通常,你应该在 Angular 里面做所有的事情,但是如果你真的想在 Angular 之外执行你的逻辑,你需要得到正确的 zone
,正如你所说的。
这个技巧滥用了 Angular 的依赖注入,并将注入的 zone
挂接到 window
对象上,如 this issue 所示。声明对 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!")