@Input() всегда всегда undefined

Я создал user photo component, который принимает значение @Input(), это значение userId. Если значение передано, я извлекаю информацию из Firebase, ссылаясь на этот userId, если это не так, я делаю что-то еще.

Моя пользовательская фото компонента

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

@Component({
    selector: 'user-photos',
    templateUrl: './user-photos.component.html',
    styleUrls: ['./user-photos.component.css']
})

export class UserPhotoComponent implements OnInit {

    @Input() userId: string;

    constructor() { 

        console.log('userId is:',this.userId);

    }


    ngOnInit() {


    }

    ngOnDestroy() {

    }
}

Как вы можете видеть, я объявил userId как @Input(), теперь на моем edit-profile component у меня есть следующее:

<user-photos [userId]="TestingInput"></user-photos>

Теперь компонент User Photo получает визуализацию, поскольку я вижу тег h1, но userId всегда undefined?

В консоли разработчика не появляются ошибки, поэтому я не совсем уверен, что я сделал неправильно.

Ответ 1

Он будет инициализирован в ngOnInit, а не в конструкторе. (Пожалуйста, также просмотрите документацию Angular Документация по жизненным циклам.)

ngOnInit() {
  console.log('userId is:',this.userId);
}

Также, если вы хотите передать литерал как строку и использовать скобки [], вы должны передать его как строку, добавив значение с одиночными тиками.

<user-photos [userId]="'TestingInput'"></user-photos>

Причина этого заключается в том, что содержащее выражение оценивается в контексте содержащего компонента, поэтому без него он попытается извлечь и передать свойство/поле с именем TestingInput, которое будет undefined (если вы также не имеете поле под этим именем).

Ответ 2

В моем случае в качестве входных данных я передавал значение undefined и предполагал, что Angular будет обрабатывать случай неопределенности так же, как сценарий по умолчанию. Это предположение было неверным, даже если оно не четко обозначено в документации по угловому взаимодействию компонентов. Вот сценарий варианта использования:

parent.component.html:

...
[mVal]="undefined"
...

child.component.ts:

...
@input('mVal')
mVal: boolean = true
...

Значение mVal будет undefined и не true, как вы могли бы ожидать.

Angular сделает значение true (регистр по умолчанию), только если оно не определено в родительском компоненте; в противном случае оно передаст значение как есть (даже если оно не undefined).

Вы можете решить эту проблему, проверив, является ли значение неопределенным в OnInit или даже в конструкторе компонента.

Ответ 3

В моем случае мне сначала пришлось использовать * ngIf = "isLoaded" на родительском шаблоне.

На родительском компоненте

    <div *ngIf = "isLoaded">
       <app-child-component [dataToChild]="dataFromParent"> </app-child-component>
    </div>

На дочернем компоненте

      @Input() dataToChild: any;
        constructor() { }
        ngOnInit(): void {
             console.log(this.dataToChild);
         }

Ответ 4

Отвечая на ваш вопрос

Значение @Input() всегда не определено

Причина, по которой вы получаете undefined в ngOnInit, заключается в том, что в момент инициализации компонента вы фактически не передали userId.

<user-photos [userId]="TestingInput"></user-photos>

Чтобы получить значение @Input в функции OnInit(), вы можете сделать что-то вроде:

Мой пользовательский фото-компонент

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

@Component({
    selector: 'user-photos',
    templateUrl: './user-photos.component.html',
    styleUrls: ['./user-photos.component.css']
})

export class UserPhotoComponent implements OnInit {

    @Input() userId: string;

    constructor() {  }

    ngOnInit() {
     setTimeout(() => {
         console.log('userId is:',this.userId);  // You will get the @Input value
     });
    }

    ngOnDestroy() {

    }
}

Ответ 5

Недавно я столкнулся с той же проблемой, и после долгих поисков я решил смешать свои идеи и в итоге получил следующее.

1. объявить объект массива данных, которые вы хотите передать, как

private sendMe: Array<{title: string}> = [];

2. поместить данные, которые вы хотите отправить в массив, как

this.sendMe.push({title: this.passMe});

3 и, наконец, передать массив, как

<app-download-section [movieTitle]="sendMe"></app-download-section>

  1. получить это как

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

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

    @Input('movieTitle') movieTitle: Array<object> = [];

    ngOnInit() { console.log(this.movieTitle); }

    }

Я нашел эту проблему