В моем шаблоне AppComponent у меня есть 3 дочерних компонента — HeaderComponent, MenuComponent, ContentComponent. Данные для дочернего компонента — MenuComponent загружаются динамически через HTTP-запрос. Если я делаю HTTP-вызов через службу в ngOnInit или конструкторе компонента, данные не загружаются, а в представлении нет данных для рендеринга. Я хочу дождаться возврата данных для меню в качестве ответа после выполнения HTTP-вызова, а затем отобразить MenuComponent с данными.

Я новичок в Angular, было бы здорово, если бы кто-нибудь предложил решение.

App.component.html

<div class="wrapper">
    <app-header></app-header>
    <app-menu></app-menu>
    <app-content></app-content>
</div>

Menu.component.ts

import { Component, OnInit } from '@angular/core';
import { MainMenuService } from "main-menu.service";

@Component({
  selector: 'app-menu',
  templateUrl: './menu.component.html',
  styleUrls: ['./menu.component.scss']
})
export class MenuComponent implements OnInit {
  mainMenuData;

  constructor(public menuService: MainMenuService) { }

  ngOnInit() {
    this.mainMenuData = this.menuService.getDataforMenu();
  }
}

Menu.component.html

<nav>
    <ul>
         <li *ngFor="let mainMenu of mainMenuData">
                <a class="main-menu" href="{{ mainMenu.href }}">{{ mainMenu.name }}</a>
          </li>
    </ul>
</nav>

Главное меню.service.ts

import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';

@Injectable({
  providedIn: 'root'
})
export class MainMenuService {
  menu;

  constructor(private httpClient: HttpClient) { }

  getDataforMenu() {
    this.httpClient.get(URL).subscribe(
      (response: any) => {
        return response;
      },
      (error: any) => {

      }
    );
  }
}
1
hanik 20 Апр 2020 в 15:48

1 ответ

Обновите свой html-файл, например

<div class="wrapper">
    <app-header></app-header>
    <app-menu *ngIf="isMenuDataLoaded"></app-menu>
    <app-content *ngIf="isContentDataLoaded"></app-content>
</div>

Затем добавьте переменные в свой файл ts, значение по умолчанию которых будет ложным, и установите его в значение true, когда вы будете использовать данные из API.

Подобно

isMenuDataLoaded = false;
isContentDataLoaded = false;

ngOnInit() {
   // your API call

  this.menuService.getDataforMenu().subscribe(
      (response: any) => {
         this.mainMenuData = response;
         this.isMenuDataLoaded = true;
      },
         (error: any) => {

     }
}

Также вам необходимо обновить свой сервис

getDataforMenu() {
   return this.httpClient.get(URL);
}

Это гарантирует, что и сообщит об угловой загрузке компонента, когда данные будут доступны.

Обратите внимание, что я использовал логическое значение только для простоты. Если вы получаете данные в виде массива, вы также можете проверить свойство .length

3
Kenny 20 Апр 2020 в 16:00
Также передайте mainMenuData в качестве входных данных для вашего компонента.
 – 
Kenny
20 Апр 2020 в 16:01
Привет, Кенни, если я должен передать mainMenuData в качестве входных данных для моего MenuComponent, тогда я должен сделать HTTP-вызов из AppComponent, верно?
 – 
hanik
20 Апр 2020 в 16:10
Да. Если вы хотите передать его в качестве ввода.
 – 
Kenny
20 Апр 2020 в 16:15
Но если ответ на этот http-вызов содержит только данные, относящиеся к конкретному компоненту, тогда сделайте вызов из этого дочернего компонента
 – 
Kenny
20 Апр 2020 в 16:16
1
Всегда имейте в виду, что если в API есть данные, которые полезны для родительского и дочернего компонентов, сделайте вызов из родительского компонента и передайте данные дочернему компоненту в качестве входных данных. Но если у API есть данные, которые полезны только для дочернего компонента, тогда сделайте вызов из самого дочернего компонента. Так как в этом случае нет смысла получать данные в родительском элементе и передавать их в качестве входных данных.
 – 
Kenny
20 Апр 2020 в 16:18