在AngularJS中,您可以使用$scope的$watch函数指定监视器以观察作用域变量的更改。那么,在Angular中观察变量的变化(例如组件变量)的等效方法是什么?
$scope.$watch()
和 $scope.$digest()
已过时。setTimeout()
而不是像$timeout
这样的东西,因为setTimeout()
是被猴子补丁过的。ChangeDetectorRef
来访问此对象。)这些变更检测器是在Angular创建组件时创建的。它们跟踪所有绑定的状态,以进行脏检查。从某种意义上说,它们类似于Angular 1为{{}}
模板绑定设置的自动$watches()
。onPush
变更检测策略),每个组件在树中被检查一次(TTL=1)……从顶部按深度优先顺序进行。(好吧,如果您处于dev模式,则变更检测运行两次(TTL=2)。有关此更多信息,请参见ApplicationRef.tick()。)它对所有绑定执行脏检查,使用那些变更检测器对象。
ngOnChanges()
来通知更改。ngDoCheck()
(有关详细信息,请参见this SO answer)。更多学习资料:
onPush
的一些内容。host
和 "Host Listeners" 部分。它解释了如何从 Angular 区域内部监听全局事件(以便触发所需的变更检测)。这个答案 有一个可工作的 plunker。 - Mark RajcokXMLHttpRequest()
,这是否意味着甚至使用HTTP请求的外部库也会触发Angular的生命周期?虽然听起来是这样的,但你可以指定“当事件在Angular区域内触发” 。另外,根据zone.js文档,似乎在任何给定时刻可以有多个区域。 - c1moore这种行为现在是组件生命周期的一部分。
一个组件可以在 OnChanges 接口中实现 ngOnChanges 方法以获取对输入变化的访问权限。
示例:
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);
}
}
<input [(ngModel)]="yourVar"></input>
是以下缩写形式:
<input [ngModel]="yourVar" (ngModelChange)="yourVar=$event"></input>
(参见例如http://victorsavkin.com/post/119943127151/angular-2-template-syntax)<input [(ngModel)]="yourVar" (ngModelChange)="changedExtraHandler($event)"></input>
getter函数
或获取器
在Angular 2上充当监视器。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);
}
}
以下是使用getter和setter函数处理模型的另一种方法。
@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;
}
}
(change)
处理程序;我也不想在我的模型的每个属性中添加get|set
; 为this.object
添加get|set
也没有用; ngOnChanges()
仅检测@Input
的更改。天啊!他们对我们做了什么?给我们一个类似于深度监视的东西! - Cody[(yourVar)]
,但是您需要实现yourVarChange
事件并在每次更改变量时调用它。@Output() heroChange = new EventEmitter();
当你的英雄被改变后,调用this.heroChange.emit(this.hero);
[(hero)]
绑定将为您完成其余工作。
请参见此处的示例:
这并没有直接回答问题,但我在不同的场合都会着陆在这个Stack Overflow问题中,以解决我在AngularJS中使用$watch的问题。最终,我采用了另一种方法来实现与$watch类似的效果,并希望在有人发现它有用时分享出来。
我使用的技巧是,在Angular服务中使用BehaviorSubject(更多内容请参见此处),让我的组件订阅它以获取(监视)变化。这类似于在angularJs中使用$watch,但需要更多设置和理解。
在我的组件中:
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;
});
}
}
在我的服务中
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});
}
}