在AngularJS中,您可以使用的$watch
功能指定观察者以观察范围变量的变化$scope
。在Angular中监视变量更改(例如,在组件变量中)相当于什么?
在AngularJS中,您可以使用的$watch
功能指定观察者以观察范围变量的变化$scope
。在Angular中监视变量更改(例如,在组件变量中)相当于什么?
Answers:
在Angular 2中,更改检测是自动的... $scope.$watch()
和$scope.$digest()
RIP
不幸的是,开发指南的“更改检测”部分尚未编写(“ 体系结构概述”页面底部“其他内容” 附近有一个占位符)。
这是我对变更检测的工作原理的理解:
setTimeout()
在组件内部使用而不是$timeout
...之类的原因,因为它setTimeout()
是猴子修补的。ChangeDetectorRef
。)这些变化检测器是在Angular创建组件时创建的。他们跟踪所有绑定的状态,以进行脏检查。从某种意义上讲,它们类似于$watches()
Angular 1为{{}}
模板绑定设置的自动功能。onPush
在任何组件上使用更改检测策略),则从树顶开始按深度优先顺序对树中的每个组件进行一次检查(TTL = 1)...。(好吧,如果您处于开发人员模式,则更改检测运行两次(TTL = 2)。有关更多信息,请参见ApplicationRef.tick()。)它将使用那些更改检测器对象对所有绑定执行脏检查。
其他参考以了解更多信息:
onPush
。host
文档中的“主机侦听器”文档。它说明了如何从Angular区域内侦听全局事件(因此将根据需要触发更改检测)。 这个答案有一个可行的工具。
现在,此行为是组件生命周期的一部分。
组件可以在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>
您可以在角2上使用getter function
或get accessor
充当手表。
在此处查看演示。
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|sets
s 添加到模型中的每个属性。添加get|set
for 会无济于事this.object
; ngOnChanges()
仅检测到@Input
s的更改。天哪!他们对我们做了什么???给我们带来某种深度的监视!
如果要使其成为2种方式的绑定,可以使用[(yourVar)]
,但是必须实现yourVarChange
event并在每次变量更改时调用它。
像这样跟踪英雄的变化
@Output() heroChange = new EventEmitter();
然后当你的英雄被改变时,打电话给 this.heroChange.emit(this.hero);
在[(hero)]
结合将完成剩下的你
在这里查看示例:
当您的应用程序仍然需要时$parse
,请尝试此操作$eval
,$watch
例如Angular中的行为
这不能直接回答问题,但是我在不同情况下都会遇到这个Stack Overflow问题,以解决在angularJs中使用$ watch的问题。我最终使用了不同于当前答案中所述的另一种方法,并希望共享它,以防有人发现它有用。
我用来实现类似$watch
功能的技术是在Angular服务中使用BehaviorSubject
(更多关于此主题的信息),然后让我的组件订阅它以获取(观看)更改。这类似于$watch
angularJs中的a,但需要更多设置和理解。
在我的组件中:
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});
}
}
这是关于Stackblitz的演示