ngOnInit не ждет вызова службы конструктора - PullRequest
0 голосов
/ 25 мая 2020

Я выполняю вызов API для конструктора компонента.

apiResult = [];
constructor(
        private router: Router,
        private applicationServices: ApplicationService,
        private location: Location,
    ) {
        this.applicationServices.getAppConfig().subscribe(
           result => {
              this.apiResult = result;
           }

Затем в ngOnInit я хочу использовать этот пример информации:

ngOnInit() {
  console.log('Selected App');
  console.log(this.apiResult );
}

Однако его чтение ngOnInit перед службой в конструкторе fini sh. Таким образом, результат «apiResult» не определен.

Какие у меня есть варианты и как лучше всего это сделать? Если возможно, вы можете привести пример.

Заранее спасибо.

Ответы [ 2 ]

3 голосов
/ 25 мая 2020

При разработке приложений Angular я бы посоветовал содержать конструкторы в чистоте и просто для управления зависимостями.

Вот что я бы рекомендовал сделать:

export class Lol {
    apiResult = [];

    constructor(
        private router: Router,
        private applicationServices: ApplicationService,
        private location: Location,
    ) { }

    ngOnInit() {
        this.applicationServices
            .getAppConfig()
            .pipe(
                tap(result => {
                    console.log('Selected App');
                    console.log(result);
                })
            )
            .subscribe(result => {
                this.apiResult = result;
            })
    }
}

Позвоните в службу поддержки в ngOnInit() и только tap результат перед подпиской, это оператор rxjs, используемый для побочных эффектов, и console.log именно он.

Обновление

Я бы рекомендовал вообще не подписываться на наблюдаемые вручную, лучше использовать для этого канал async. Таким образом вы избежите возможных утечек памяти и позволите angular управлять подписками за вас.

Это будет файл компонента:

export class LolComponent {
  apiResult$: Observable<any[]>;

  constructor(
    private router: Router,
    private applicationServices: ApplicationService,
    private location: Location
  ) {}

  ngOnInit() {
    this.apiResult$ = this.applicationServices.getAppConfig().pipe(
      tap((result) => {
        console.log("Selected App");
        console.log(result);
      })
    );
  }
}

Это будет шаблон:

<div class="container" *ngIf="(apiResult$ | async) as apiResult">
    {{ apiResult | json }}
</div>
0 голосов
/ 25 мая 2020

Фактическая причина в том, что зависимости (параметры вашего конструктора) вводятся, а сам компонент создается. Во время добавления этого компонента в DOM в зависимости от некоторых ситуаций выполняются различные функции жизненного цикла.

Другое дело, что ваш .getAppConfig() возвращает Observable, который является асинхронной функцией. Здесь функция .getAppConfig() будет выполняться в вашем constructor, но в то же время выполняется ngOnInit (). Итак, очевидно, что this.apiResult будет пустым в это время, потому что присвоение значений этому массиву еще не выполнено.

Итак, решение может быть следующим:

apiResult = [];
constructor(
        private router: Router,
        private applicationServices: ApplicationService,
        private location: Location,
    ) {   }

ngOnInit(){
 this.applicationServices.getAppConfig()
       .subscribe(result => {
              this.apiResult = result;
              consoloe.log(this.apiResult);
       });
}

Здесь, как все подсказывает, сохраните определение конструктора в чистоте для лучших практик.

Вы можете прочитать об asyn c и нормальные функциональные различия. Также, самое главное, Observables.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...