Angular @Input() не привязывается и не работает в Angular 7

У меня есть мастер-шаблон с таким компонентом:

   <h2>My Heroes</h2>
<ul class = "heroes">
  <li *ngFor = "let hero of heroes"
    [class.selected] = "hero === selectedHero"
    (click) = "onSelect(hero)">
    <span class = "badge">{{hero.id}}</span> {{hero.name}}
  </li>
</ul>

<app-hero-detail [hero] = "selectedHero"></app-hero-detail>]

Главный компонент выглядит следующим образом:

import { Component, OnInit } from '@angular/core';

import { Hero } from '../hero';
import { HeroService } from '../hero.service';

@Component({
  selector: 'app-heroes',
  templateUrl: './heroes.component.html',
  styleUrls: ['./heroes.component.css']
})
export class HeroesComponent implements OnInit {

  public selectedHero: Hero;

  heroes: Hero[];

  constructor(private heroService: HeroService) { }

  ngOnInit() {
    this.getHeroes();
  }

  onSelect(hero: Hero): void {

    this.selectedHero = hero;
  }

  getHeroes(): void {
    this.heroService.getHeroes()
        .subscribe(heroes => this.heroes = heroes);
  }
}

Шаблон Master получает данные от службы.

При нажатии на основной элемент в списке отображаются дочерние детали.

Используя это в мастере:

 <li *ngFor = "let hero of heroes"
[class.selected] = "hero === selectedHero"
(click) = "onSelect(hero)">

и привязка к

<app-hero-detail [hero] = "selectedHero"></app-hero-detail>]

Но я получаю эту ошибку в консоли.

ERROR TypeError: Cannot read property 'name' of undefined at HeroDetailComponent.push../src/app/hero-detail/hero-detail.component.ts.HeroDetailComponent.ngOnInit (hero-detail.component.ts:19) at checkAndUpdateDirectiveInline (core.js:22099) at checkAndUpdateNodeInline (core.js:23363) at checkAndUpdateNode (core.js:23325) at debugCheckAndUpdateNode (core.js:23959) at debugCheckDirectivesFn (core.js:23919) at Object.eval [as updateDirectives] (HeroesComponent.html:10) at Object.debugUpdateDirectives [as updateDirectives] (core.js:23911) at checkAndUpdateView (core.js:23307) at callViewAction (core.js:23548)

Мой дочерний компонент выглядит так:

import { Component, OnInit, Input } from '@angular/core';
import { Hero } from '../hero';
import { HeroService } from '../hero.service';

@Component({
  selector: 'app-hero-detail',
  templateUrl: './hero-detail.component.html',
  styleUrls: ['./hero-detail.component.css']
})
export class HeroDetailComponent implements OnInit {

  @Input() hero: Hero;

  heroes: Hero[];

  constructor(private heroService: HeroService) {  }
  i: string;
  ngOnInit() {
    this.i = this.hero.name

    this.getHeroes();

  }
  getHeroes(): void {

    this.heroService.getHeroes(this.i)
      .subscribe(heroes => this.heroes = heroes);
  }

}

Обратите внимание: я использую следующее для привязки:

@Input() hero: Hero; // in child component to parent template 
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Angular и React для вашего проекта веб-разработки?
Angular и React для вашего проекта веб-разработки?
Когда дело доходит до веб-разработки, выбор правильного front-end фреймворка имеет решающее значение. Angular и React - два самых популярных...
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Мы провели Twitter Space, обсудив несколько проблем, связанных с последними дополнениями в Angular. Также прошла Angular Tiny Conf с 25 докладами.
Угловой продивер
Угловой продивер
Оригинал этой статьи на турецком языке. ChatGPT используется только для перевода на английский язык.
Мое недавнее углубление в Angular
Мое недавнее углубление в Angular
Недавно я провел некоторое время, изучая фреймворк Angular, и я хотел поделиться своим опытом со всеми вами. Как человек, который любит глубоко...
Освоение Observables и Subjects в Rxjs:
Освоение Observables и Subjects в Rxjs:
Давайте начнем с основ и постепенно перейдем к более продвинутым концепциям в RxJS в Angular
1
0
1 011
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

используйте ngOnChanges, чтобы проверить, установлено ли входное значение

  ngOnChanges() {
    if (!this.hero) return null;
    this.i = this.hero.name

    this.getHeroes();

  }

Есть много подобных вопросов к этому ОП. Но на самом деле это решает, как мы можем получить данные из API, переданные от родителя к дочернему свойству @input. Если вы хотите консольировать данные, они будут неопределенными в ngOnInit. Это метод (жизненный цикл), где нам нужно это сделать - спасибо! Идеальный ответ.

Gel 30.07.2020 17:52

onInit, hero может быть не определен, он заполняется после инициализации компонента. Вы можете попробовать использовать

@Input() set hero (value) {
   if (value) {
      this.i = this.hero.name;
   }
}

Другие вопросы по теме