无论分离设置如何,更改检测似乎都发生在单击事件上
Change detection appears to occur on click event regardless of detached setting
这可能是我自己对 Angular 2 变化检测如何工作的误解,但我本以为如果组件的 ChangeDetectionStrategy
设置为 Checked
,CheckOnce
或 Detached
,该组件只会在组件实例化时检查一次更改。它似乎不是那样发生的。
import {Component, OnInit, ChangeDetectionStrategy} from 'angular2/core'
@Component({
selector: 'my-app',
providers: [],
template: `
<div>
<button
(click)="onClick($event)"
[class.thing]="hasThingClass()">Update</button>
</div>
`,
changeDetection:ChangeDetectionStrategy.CheckOnce,
styles: [`
.thing { background-color: red }
`]
})
export class App implements OnInit {
public hasThing:Boolean = false;
onClick() {
this.hasThing = !this.hasThing;
}
hasThingClass(e) {
return this.hasThing;
}
}
单击时我希望切换 hasThing
属性 但我不希望视图更新。碰巧的是,视图确实更新了。当 ChangeDetectionStrategy
设置为 Detached
时也会发生。
http://plnkr.co/edit/2hHdt2BDpj419Z32iPjJ?p=preview
我在这里错过了什么?究竟是什么导致视图更新?据我所知,无论我更新 hasThing
属性,无论值是否已更改,视图都会在单击时更新。
我希望这能帮助你理解它:)
http://plnkr.co/edit/sM8CCSl8hXyRVAaTZH4N?p=preview
假设我们有一个我在服务中模拟的异步事件:
import { Injectable } from 'angular2/core';
@Injectable()
export class DataProvider {
data = 1;
constructor() {
// async data change simulation
setInterval(() => {
this.data = this.data * 2;
}, 500);
}
}
当 angular 通过区域 api 发现任何异步事件更改时,区域通知 angular 在该上下文中发生了异步事件并将其传播到 angular 更改detection api 在实际视图和组件之间进行检查,在下面的示例中我们可以看到,由于更改检测行为未更改 angular 不断更新视图:
import {
Component
} from 'angular2/core';
import { bootstrap } from 'angular2/platform/browser';
import { DataProvider } from './data-provider';
import { TriggerDataChange } from './data-change-trigger';
@Component({
selector: 'app',
template: `
<div>Live Update: {{dataProvider.data}} </div>
<data-change-trigger></data-change-trigger>
`,
providers: [DataProvider],
directives: [TriggerDataChange]
})
class App {
constructor(private dataProvider:DataProvider) {}
}
bootstrap(App);
场景二更改检测的行为已更改,因为 ChangeDetectionStrategy 设置为 CheckOnce angular 将仅在组件初始化过程中触发一次更改检测,在这种情况下,您必须手动触发更改以更新视图本例通过事件绑定完成:
import {
Component,
ChangeDetectionStrategy,
ChangeDetectorRef
} from 'angular2/core';
import { DataProvider } from './data-provider';
@Component({
selector: 'data-change-trigger',
changeDetection: ChangeDetectionStrategy.CheckOnce,
template: `
Trigger update:
<button (click)="update($event)">Update</button>
<div>{{dataProvider.data}}</div>
`
})
export class TriggerDataChange {
constructor(
private ref: ChangeDetectorRef,
private dataProvider:DataProvider
) {}
update($event) {
console.log('event', $event);
}
}
最后回答为什么您的案例视图已更新?这是因为模板中的事件绑定:
(click)="onClick($event)"
这是触发当前组件的本机事件 ChangeDetectorRef.detectChanges()
无论 ChangeDetectionStrategy 设置如何,Angular 都会在
时检查组件的更改
- 组件触发事件
- 一个 observable 触发了一个事件,并且异步管道在具有该 observable 的视图中使用
想法是...如果组件触发了一个事件,或者绑定的可观察值发生了变化,很可能您想更新它的视图。
这可能是我自己对 Angular 2 变化检测如何工作的误解,但我本以为如果组件的 ChangeDetectionStrategy
设置为 Checked
,CheckOnce
或 Detached
,该组件只会在组件实例化时检查一次更改。它似乎不是那样发生的。
import {Component, OnInit, ChangeDetectionStrategy} from 'angular2/core'
@Component({
selector: 'my-app',
providers: [],
template: `
<div>
<button
(click)="onClick($event)"
[class.thing]="hasThingClass()">Update</button>
</div>
`,
changeDetection:ChangeDetectionStrategy.CheckOnce,
styles: [`
.thing { background-color: red }
`]
})
export class App implements OnInit {
public hasThing:Boolean = false;
onClick() {
this.hasThing = !this.hasThing;
}
hasThingClass(e) {
return this.hasThing;
}
}
单击时我希望切换 hasThing
属性 但我不希望视图更新。碰巧的是,视图确实更新了。当 ChangeDetectionStrategy
设置为 Detached
时也会发生。
http://plnkr.co/edit/2hHdt2BDpj419Z32iPjJ?p=preview
我在这里错过了什么?究竟是什么导致视图更新?据我所知,无论我更新 hasThing
属性,无论值是否已更改,视图都会在单击时更新。
我希望这能帮助你理解它:)
http://plnkr.co/edit/sM8CCSl8hXyRVAaTZH4N?p=preview
假设我们有一个我在服务中模拟的异步事件:
import { Injectable } from 'angular2/core';
@Injectable()
export class DataProvider {
data = 1;
constructor() {
// async data change simulation
setInterval(() => {
this.data = this.data * 2;
}, 500);
}
}
当 angular 通过区域 api 发现任何异步事件更改时,区域通知 angular 在该上下文中发生了异步事件并将其传播到 angular 更改detection api 在实际视图和组件之间进行检查,在下面的示例中我们可以看到,由于更改检测行为未更改 angular 不断更新视图:
import {
Component
} from 'angular2/core';
import { bootstrap } from 'angular2/platform/browser';
import { DataProvider } from './data-provider';
import { TriggerDataChange } from './data-change-trigger';
@Component({
selector: 'app',
template: `
<div>Live Update: {{dataProvider.data}} </div>
<data-change-trigger></data-change-trigger>
`,
providers: [DataProvider],
directives: [TriggerDataChange]
})
class App {
constructor(private dataProvider:DataProvider) {}
}
bootstrap(App);
场景二更改检测的行为已更改,因为 ChangeDetectionStrategy 设置为 CheckOnce angular 将仅在组件初始化过程中触发一次更改检测,在这种情况下,您必须手动触发更改以更新视图本例通过事件绑定完成:
import {
Component,
ChangeDetectionStrategy,
ChangeDetectorRef
} from 'angular2/core';
import { DataProvider } from './data-provider';
@Component({
selector: 'data-change-trigger',
changeDetection: ChangeDetectionStrategy.CheckOnce,
template: `
Trigger update:
<button (click)="update($event)">Update</button>
<div>{{dataProvider.data}}</div>
`
})
export class TriggerDataChange {
constructor(
private ref: ChangeDetectorRef,
private dataProvider:DataProvider
) {}
update($event) {
console.log('event', $event);
}
}
最后回答为什么您的案例视图已更新?这是因为模板中的事件绑定:
(click)="onClick($event)"
这是触发当前组件的本机事件 ChangeDetectorRef.detectChanges()
无论 ChangeDetectionStrategy 设置如何,Angular 都会在
时检查组件的更改- 组件触发事件
- 一个 observable 触发了一个事件,并且异步管道在具有该 observable 的视图中使用
想法是...如果组件触发了一个事件,或者绑定的可观察值发生了变化,很可能您想更新它的视图。