【问题标题】:Angular event method getting called multiple timesAngular事件方法被多次调用
【发布时间】:2018-11-12 17:35:36
【问题描述】:

在我的app.component.ts 中,我正在进行 API 调用并获取 userDetails。然后我发出这个userDetails。我在我的header 组件中订阅了这个userDetails。我的标头组件使用app-my-image-logo 组件。在页面刷新时,调用 API 并获取 userDetails。之后,事件被发出,因此,testnDisplay 方法被调用。但我的问题是每隔几秒钟,我就会在控制台上得到以下输出。

img   my-image-logo.component.ts:28
name  my-image-logo.component.ts:28
img   my-image-logo.component.ts:28
name  my-image-logo.component.ts:28
img   my-image-logo.component.ts:28
name  my-image-logo.component.ts:28
img   my-image-logo.component.ts:28
name  my-image-logo.component.ts:28

所以,这个方法在频繁的间隔后被多次调用,但它应该只被调用一次。

header.component.html

<app-my-image-logo ></app-my-image-logo>

header.component.ts

ngOnInit() {
        const self = this;
        this.userDetails = this.dataService.getUserDetails();
        this.dataService.userDetailsEvt.subscribe(
            function(data){
                self.userDetails = data;
            }
        );

    }

这是app-my-logo 组件。

app-logo.component.html

<img #imgDiv  [hidden]="testnDisplay('img')" >

<div [hidden]="testnDisplay('name')"
     ></div>

app-logo.component.ts

testnDisplay(type){
        console.log(type);
}

这是我的dataService

data.service.ts

setUserDetails(userDetails){
        this.userDetails = userDetails;
        this.userDetailsEvt.emit(this.userDetails);
    }

    getUserDetails(){
        return this.userDetails;
    }

app.component.ts

this.authService.httpPost("/auth/getUserDetails", payload).subscribe(
            function (data: any) {
                self.dataService.setUserDetails(data);
            },
            function(error){

            }
        );

【问题讨论】:

    标签: angular


    【解决方案1】:

    这是因为您在组件上使用了Default 更改检测策略。默认情况下,所有组件都使用此策略,这意味着当 Angular 确定组件的状态为脏时,它会重新渲染模板并导致调用 testnDisplay 函数。为了从默认检查中删除组件,您应该将策略设置为 OnPush,这会更加高效,因为它仅在 @Input 属性之一更改时重新呈现模板。仍然可以重新渲染模板,但它需要组件告诉 Angular 何时这样做。示例:

    @Component({
      /* ... */
      changeDetection: ChangeDetectionStrategy.OnPush
    })
    export class AppLogoComponent  {
      testnDisplay(type){
        console.log(type);
      }
    }
    

    【讨论】:

    • 谢谢泰迪,这行得通,但我仍然很困惑。为什么Default 类别在没有更改任何值时会将组件的状态视为脏? EventEmitter 只改变一次值,所以应该只调用一次。
    • 默认行为是在 Angular 认为某些事情可能发生变化时重新渲染。 Angular 认为在触发事件、发生 XHR 或触发计时器(基本上所有异步操作)后,某些东西可能会发生变化。它使用区域来确定哪些组件可能会受到影响,然后告诉这些组件重新渲染。 blog.thoughtram.io/angular/2016/02/22/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-28
    • 1970-01-01
    • 1970-01-01
    • 2023-03-04
    • 2014-11-02
    相关资源
    最近更新 更多