加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

Angular 2单击事件回调,不会触发更改检测

发布时间:2020-12-17 17:02:01 所属栏目:安全 来源:网络整理
导读:我在尝试在Angular 2中的(单击)事件回调函数内执行某些逻辑时遇到了很大的麻烦,而没有触发变化检测. 为什么我不想触发变化检测 回调函数执行简单的动画滚动到顶部.它不会影响其他任何组件,因此我不需要在每个组件中进行变化检测,实际上我真的不希望它开火!
我在尝试在Angular 2中的(单击)事件回调函数内执行某些逻辑时遇到了很大的麻烦,而没有触发变化检测.

为什么我不想触发变化检测

回调函数执行简单的动画滚动到顶部.它不会影响其他任何组件,因此我不需要在每个组件中进行变化检测,实际上我真的不希望它开火!由于变化检测在每个组件中都会触发,因此动画在移动设备上的性能极差.

我试过的

我知道我可以使用区域外的代码运行

this._zone.runOutsideAngular(() => {
    someFunction();
})

当你想在区域外运行的代码没有被click,keyup,keydown事件等调用时,这很有效.

因为我的组件看起来像……

< button(click)=“doThing()”>在区域外做那件事!< / button>

doThing() {
    this._zone.runOutsideAngular(() => {
        myFunction();
    })
}

… myFunction将在区域外运行,但click事件将触发更改检测.

我已经在尽可能多的组件中实现了OnPush变更检测策略.

重要的是,此处不会触发更改检测,但我找不到阻止它的方法.

编辑
请参见此plnk,并在所有组件中将更改检测设置为OnPush.单击子行组件按钮会在子行,行和应用程序组件中触发CD.

解决方法

如上所述,即使将发生单击事件的组件设置为OnPush,仍会导致触发更改检测.

开箱即用的事件处理

@Component({
    selector: 'test'
    template: `<button (click)="onClick($event)">Click me</button>`,changeDetection: ChangeDetectionStrategy.OnPush
})
export class MyComponent {

    onClick(e:Event) {
        e.preventDefault();
        e.stopPropagation();

        this._zone.runOutsideAngular(() => {
            // gets run outside of Angular but parent function still triggers change detection
        });

        return false;

        /*
         * change detection always triggered
         * regardless of what happens above
         */
     }

 }

大多数时候这可能不是问题,但是当渲染和绘制某些函数的性能是必不可少的时候,我采用的方法是完全绕过Angular的内置事件处理.根据我自己的实验,以下似乎是解决这个问题的最简单,最易维护的方法.

绕过开箱即用的事件处理

这里的想法是使用RxJS手动绑定到我想要的任何事件,在这种情况下是一个点击,使用Observable.fromEvent.此示例还演示了清理事件订阅的实践.

import {Component,ElementRef,OnInit,OnDestroy,NgZone} from '@angular/core';
import {Observable} from 'rxjs/Observable';
import {Subscription} from 'rxjs/Subscription';

@Component({
    selector: 'test'
    template: `<button #myButton>Click me</button>`,changeDetection: ChangeDetectionStrategy.OnPush
})
export class MyComponent implements OnInit {

    private _subs:Subscription[] = [];

    // reference to template variable
    @ViewChild('myButton') myButton:ElementRef;

    constructor(private _zone:NgZone){}

    ngOnInit() {
        this.manuallyBindToViewEvents();
    }

    manuallyBindToViewEvents() {
        this.subscribeToMyButton()
    }

    subscribeToMyButton() {
        let sub:Subscription;

        this._zone.runOutsideAngular(() => {
            sub = Observable.fromEvent(this.myButton.nativeElement,'click').subscribe(e => {
                console.log('Yayyyyy! No change detection!');
            })
        });

        this._subs.push(sub);
    }

    ngOnDestroy() {
        // clean up subscriptions
        this._subs.forEach(sub => sub.unsubscribe());
    }

}

希望这会对类似情况下的其他人有所帮助.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读