【问题标题】:@Input() value is always undefined@Input() 值始终未定义
【发布时间】:2017-06-26 15:56:15
【问题描述】:

我创建了一个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 标记出现时,User Photo 组件被渲染,但是 userId 始终未定义?

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

【问题讨论】:

    标签: angular typescript


    【解决方案1】:

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

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

    此外,如果您想传递像字符串这样的文字并使用方括号 [],则必须通过将值括在单个刻度上来将其作为字符串传递。

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

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

    【讨论】:

    • 可以确认它有效,非常感谢您的帮助和其他信息。暂时无法接受答案,需要等待三分钟。会尽快处理的。
    【解决方案2】:

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

    在父组件上

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

    在子组件上

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

    【讨论】:

    • 我能够使用此代码。 &lt;div *ngIf = "dataFromParent"&gt; &lt;app-child-component [dataToChild]="dataFromParent"&gt; &lt;/app-child-component&gt; &lt;/div&gt;
    • @user2814648 一年多后我只想说 - 经过 4 个小时的压缩 stackoverflow,你的答案是有效的。非常感谢!
    • *ngIf 确实如此!谢谢兄弟!
    【解决方案3】:

    如果您的输入出现延迟(例如,网络服务速度较慢),则在响应从网络服务到达之前,该值首先是未定义的。

    为了调试这个,你可以使用 ngOnChanges() 钩子,它会在每次输入值改变时触发:

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

    这将输出如下内容:

    data undefined

    data here it is!

    【讨论】:

      【解决方案4】:

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

      parent.component.html:

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

      child.component.ts:

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

      mVal 的值将是 undefined,而不是您可能预期的 true

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

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

      【讨论】:

        【解决方案5】:

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

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

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

        【讨论】:

          【解决方案6】:

          回答你的问题

          @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() {
          
              }
          }
          

          【讨论】:

            【解决方案7】:

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

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

            【讨论】:

              【解决方案8】:

              如果您想使用硬编码字符串作为参数,请使用单个刻度

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

              【讨论】:

                猜你喜欢
                • 2018-11-02
                • 2019-10-30
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2021-11-21
                • 1970-01-01
                相关资源
                最近更新 更多