无论分离设置如何,单击事件似乎都会发生更改检测 [英] Change detection appears to occur on click event regardless of detached setting

查看:84
本文介绍了无论分离设置如何,单击事件似乎都会发生更改检测的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这可能是我对Angular 2更改检测的工作原理的误解,但我希望如果将组件的 ChangeDetectionStrategy 设置为 Checked CheckOnce Detached ,则该组件仅在实例化时检查一次更改.看来不是这样.

This may be my own misunderstanding of how Angular 2 change detection works but I would have expected that if a component's ChangeDetectionStrategy was set to Checked, CheckOnce or Detached, that that component would only check for changes once when the component is instantiated. It appears to not happen that way.

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 时,也会发生这种情况.

On click I would have expected to toggle the hasThing property but I wouldn't have expected the view to update. As it happens, the view does update. The occurs when the ChangeDetectionStrategy is set to Detached also.

http://plnkr.co/edit/2hHdt2BDpj419Z32iPjJ?p=preview

我在这里想念什么?究竟是什么导致视图更新?据我所见,无论我是否更新 hasThing 属性,该视图在单击时都会更新,无论值是否已更改.

What am I missing here? What exactly is causing the view to update? From what I can see, regardless of me updating the hasThing property, the view updates on click whether a value has changed or not.

推荐答案

我希望这可以帮助您理解它:)

I hope this will help you understand it :)

http://plnkr.co/edit/sM8CCSl8hXyRVAaTZH4N?p=preview

假设我们有一个异步事件,我在服务中进行了模拟:

Let's say we have an async event which i simulate in my service:

import { Injectable } from 'angular2/core';

@Injectable()
export class DataProvider {
  data = 1;
  constructor() {
    // async data change simulation
    setInterval(() => {
      this.data = this.data * 2;
    }, 500);
  }
}

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

When angular spot any async event change via zones api , zone notify an angular in that context an async event happened and it propagate it to angular change detection api to do check between actual view and component, and in example below we can see that since change detection behaviour is not changed angular is constantly updating view:

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

Scenario two with changed behaviour of change detection, since ChangeDetectionStrategy is set to CheckOnce angular will trigger change detection only once at component initialization process and in that case you have to trigger change manually to update view which in this case is done by event binding:

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

最后回答为什么在您的情况下视图已更新?这是因为模板中的事件绑定:

And finally to answer why is in your case view is updated ? It's because event binding in template:

(click)="onClick($event)" 

这是一个本地事件,正在触发当前组件ChangeDetectorRef.detectChanges()

This is an native event which is triggering current component ChangeDetectorRef.detectChanges()

这篇关于无论分离设置如何,单击事件似乎都会发生更改检测的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆