1

这可能是我自己对 Angular 2 更改检测如何工作的误解,但我原以为如果组件ChangeDetectionStrategy设置为或Checked,则该组件只会在组件实例化时检查更改一次。它似乎不会以这种方式发生。CheckOnceDetached

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属性,视图都会在单击时更新,无论值是否已更改。

4

2 回答 2

6

无论 ChangeDetectionStrategy 设置如何,Angular 都会在任何时候检查组件的更改

  • 组件触发事件
  • 一个 observable 触发一个事件,并且 async 管道在视图中与该 observable 一起使用

这个想法是......如果组件触发了一个事件,或者一个绑定的可观察值发生了变化,你很可能想要更新它的视图。

于 2016-03-23T14:12:07.620 回答
4

我希望这能帮助你理解它:)

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);
  }
}

当角度通过区域 api 发现任何异步事件发生变化时,区域会通知该上下文中的角度发生异步事件并将其传播到角度变化检测 api 以在实际视图和组件之间进行检查,在下面的示例中,我们可以看到自从变化检测行为没有改变 角度不断更新视图:

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 角度将在组件初始化过程中仅触发一次更改检测,在这种情况下,您必须手动触发更改以更新视图,在这种情况下通过事件绑定完成:

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() 的本机事件

于 2016-03-23T14:12:01.260 回答