@Input () значение не определено - PullRequest
0 голосов
/ 05 августа 2020

Я создал компонент, который принимает значение @Input(), но всегда получаю undefind. Вот мой код:

parent. html

<added-item
      [minItemValueLength]="minItemValueLength"
      [maxItemValueLength]="maxItemValueLength"
      [listOfItems]="listOfItems"
  ></added-item>

children.ts

export class AddedItemComponent implements OnInit, OnChanges{

  @Input() minItemValueLength: number;
  @Input() maxItemValueLength: number;
  @Input() listOfItems: string[];

  ngOnInit() {
    console.log(this.minItemValueLength)      // return 3 
    console.log(this.listOfItems)             // return undefined
  }
}

parent.ts

export class LocationsTabComponent implements OnInit {
  listOfItems: string[];
  minItemValueLength = 3;
  maxItemValueLength = 15;

  public ngOnInit(): void {
    this.locationService.getLocations().subscribe((locations) => {
      this.getLocationsList();
      console.log(this.listOfItems)    // return Array(6)
    });
  }
  private getLocationsList() {
    this.listOfItems = this.locations.map((location: Location) => location.name);
    console.log(this.listOfItems)    // return Array(6)
  }
}

Если я используйте ngOnChanges() в детях, чем сначала выведите меня:

data undefined, а затем:

data Array(6)

Как я могу получить это значение в onInit ?

Буду очень признателен за любую помощь!

Ответы [ 3 ]

1 голос
/ 05 августа 2020

С момента подписки на местоположения вы можете использовать asyn c, чтобы дождаться полного разрешения ответа, иначе вам придется реализовать интерфейс OnChanges.

public async ngOnInit(): void {
await this.locationService.getLocations().toPromise().then((locations) => {
  this.getLocationsList();
  console.log(this.listOfItems)    // return Array(6)
});
}
private getLocationsList() {
  this.listOfItems = this.locations.map((location: Location) => location.name);
  console.log(this.listOfItems)    // return Array(6)
}
1 голос
/ 05 августа 2020

Значение не всегда undefined только во время создания компонента, и это потому, что вы передали его как таковой.

Процесс:

  1. Родитель создает и ngOnInit запускается.
  2. ngOnInit имеет метод Observable \ Promise \ Asyn c, что означает, что мы не ждем ответа, поэтому значение все еще не определено.
  3. Дочерний компонент создается и выполняет ngOnInit. значение все еще не определено.
  4. Метод Observable\Promise\Async теперь, наконец, завершен, и пользовательский обратный вызов, который вы создали, теперь присвоил значение, и значение передается дочернему компоненту. Так что, конечно, дочерний ngOnInit не примет его, потому что компонент уже был создан.

Есть несколько решений:

  1. Поместите *ngIf="listOfItems" на added-item .
  2. Украсить родительский элемент как async ngOnInit, изменить: .subscribe на .toPromise, например: await this.locationService.getLocations().toPromise..., теперь родительский ngOnInit будет ждать ответа.
1 голос
/ 05 августа 2020

Это потому, что вы назначаете

listOfItems = ...

в методе обратного вызова asyn c.

Если вы хотите обнаружить изменения, вы должны реализовать интерфейс onChanges и реализовать соответствующий хук метод.

export class AddedItemComponent implements OnInit, OnChanges{

    @Input() minItemValueLength: number;
    @Input() maxItemValueLength: number;
    @Input() listOfItems: string[];

    ngOnInit() {
        console.log(this.minItemValueLength)      // return 3 
        console.log(this.listOfItems)             // return undefined
    }
    
    ngOnChanges(changes: SimpleChanges): void {
        if (changes.listOfItems) {
            console.log(this.listOfItems)
        }
    }

}
...