Метод углового события вызывается несколько раз

#angular #typescript

Вопрос:

В моем app.component.ts я делаю вызов API и извлекаю userDetails . Затем я излучаю это userDetails . Я подписался на это userDetails в своем header компоненте. Мой компонент заголовка использует app-my-image-logo компонент. При обновлении страницы вызывается API и извлекаются данные пользователей. После этого генерируется событие и, следовательно, 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>
 

заголовок.компонент.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>
 

приложение-логотип.компонент.ts

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

Это мой dataService :

data.service.ts

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

    getUserDetails(){
        return this.userDetails;
    }
 

приложение.компонент.ts

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

            }
        );
 

Ответ №1:

Это связано с тем, что вы используете Default стратегию обнаружения изменений в своем компоненте. По умолчанию все компоненты используют эту стратегию, что означает, что, когда Angular определяет, что состояние компонента загрязнено, он повторно отображает шаблон и вызывает testnDisplay вызов функции. Чтобы удалить компонент из проверки по умолчанию, вы должны установить стратегию OnPush , которая является гораздо более эффективной, поскольку она повторно отображает шаблон только при изменении одного из @Input свойств. По-прежнему возможно повторное отображение шаблона, но для этого требуется, чтобы компонент сообщал angular, когда это нужно сделать. Пример:

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

Комментарии:

1. Спасибо, Тедди, это работает, но я все еще в замешательстве. Почему Default категория будет рассматривать состояние компонента как грязное, если значение не изменяется? EventEmitter изменяет значение только один раз, поэтому его следует вызывать только один раз.

2. Поведение по умолчанию говорит о повторной визуализации всякий раз, когда Angular думает, что что-то могло измениться. Угловой думает, что что-то могло измениться после запуска события, появления XHR или срабатывания таймера (в основном все асинхронные действия). Он использует зоны, чтобы определить, какие компоненты могут быть затронуты, а затем сообщает им о повторной визуализации. blog.thoughtram.io/angular/2016/02/22/…