@Input()值始终未定义

时间:2017-02-08 20:40:25

标签: angular typescript

我创建了user photo component,其值为@Input(),此值为userId。如果传入该值,那么我将从链接到此userId的Firebase检索信息,如果没有,则我会执行其他操作。

我的用户照片组件

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>

现在,当我看到h1标签出现时,用户照片组件会呈现,但是userId始终未定义?

开发人员控制台中没有出现任何错误,所以我不完全确定我做错了什么。

9 个答案:

答案 0 :(得分:67)

它将在ngOnInit中初始化,而不是构造函数。 (还请查看Angular Life Cycle Hooks documentation

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

此外,如果你想传递像字符串一样的文字,并使用括号[],你必须将它作为一个字符串传递,方法是用单个刻度括起来。

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

原因是包含表达式是在包含组件的上下文中计算的,所以如果没有它,它将尝试检索并传递一个名为TestingInput的属性/字段,这将是未定义的(除非你也会发生一个具有该名称的字段)。

答案 1 :(得分:7)

在我的情况下,我将undefined作为 input 传入,并且我假设Angular将undefined的情况与默认方案相同。即使Angular's Component Interaction documentation中没有明确概述,该假设也是错误的。这是用例场景:

parent.component.html:

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

child.component.ts:

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

mVal的值将是undefined,而不是您所期望的true

只有在父组件上未定义 时,Angular才会使该值为true(默认情况下)。否则,它将按原样传递值(即使它是undefined)。

您可以通过检查OnInit或组件的构造函数中值是否未定义来解决此问题。

答案 2 :(得分:1)

在我的情况下,我必须首先在父级模板上使用* ngIf =“ isLoaded”。

在父组件上

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

关于子组件

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

答案 3 :(得分:1)

如果 TestingInput 是一个变量并且不是值最好添加*ngIf="TestingInput"

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

如果我们正在调用一些api,响应的延迟可能会导致传递一个空值

答案 4 :(得分:0)

回答您的问题

  

@Input()值始终未定义

在ngOnInit中未定义的原因是,在初始化组件时,您实际上尚未传递userId。

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

为了在OnInit()函数中获取@Input值,您可以执行以下操作:

  

我的用户照片组件

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 :(得分:0)

如果您的输入出现延迟(例如网络服务运行缓慢),则该值首先将是不确定的,直到响应从网络服务到达为止。

为了对此进行调试,您可以使用ngOnChanges()钩子,该钩子每次输入值发生更改时都会触发:

ngOnChanges() {
  console.log('data', this.data);
}

它将输出类似的内容

data undefined <-OnInit,值尚未到达

data here it is! <-值延迟到达

答案 6 :(得分:0)

这些答案中的任何一个都不适合我,经过一些研究,我找到了爱的解决方案,

在HTML中。

<app-opportunityTable [tableNAme]="'OPPORTUNITY'"></app-opportunityTable>

在子组件中

@Component( {
    selector: 'app-opportunityTable',
    templateUrl: './opportunityTable.component.html',
    styleUrls: ['./opportunityTable.component.css'],
    inputs: ['tableNAme']
} )

export class opportunityTable implements OnInit {
         ngOnInit() {
        console.log( "this is it" + this.tableNAme )
         }
}

答案 7 :(得分:0)

如果您想使用硬编码的字符串作为参数,请使用单跳号

<app-mycomponent [inputProperty]="'test'"></app-mycomponent>

答案 8 :(得分:-2)

我最近遇到了同样的问题,经过漫长的搜索,我决定混合我的想法并得出以下结论。

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); }

    }

我找到了这个related issue