Angular组件的Input()属性未定义

时间:2018-11-02 02:10:29

标签: angular

为什么未定义此属性?

export class DataFormComponent implements OnInit {

  distanceDropdownItems: any[];

  constructor() { }

  ngOnInit() {
    this.distanceDropdownItems = DISTANCE_DROPDOWN_ITEMS;
    console.log('FORMS dropdown items = ', this.distanceDropdownItems); < ---- defined ... [{},{},...]
  }

}

模板:

<app-input-dropdown [dropdownItems]="distanceDropdownItems"></app-input-dropdown>

子组件:

@Component({
  selector: 'app-input-dropdown',
  templateUrl: './input-dropdown.component.html',
  styleUrls: ['./input-dropdown.component.scss'],
  encapsulation: ViewEncapsulation.None
})
export class InputDropdownComponent implements OnInit {

  @Input() dropdownItems: any[];

  selectedItem: any;

  constructor(private el: ElementRef) { }

  ngOnInit() {
    console.log(this.dropdownItems);  <------- Undefined
    this.selectedItem = this.dropdownItems[0];

    const dropdownButton = this.el.nativeElement.querySelector('.dropdown-button');
    dropdownButton.classList.remove('dropdown-button');
    dropdownButton.classList.add('dropdown-input-button');

  }

}

4 个答案:

答案 0 :(得分:1)

您使用的是 items 而不是您在父组件中显示的 distanceDropdownItems ,请尝试如下更改变量名称,

<app-input-dropdown [dropdownItems]="distanceDropdownItems"></app-input-dropdown>

为避免未定义或空错误,您可以在父组件上使用* ngIf来确保在初始化子组件时dropdownItems不会引发任何错误

<app-input-dropdown *ngIf="distanceDropdownItems"  [dropdownItems]="this.distanceDropdownItems"></app-input-dropdown>

编辑

现在,编辑后看起来您在子组件上使用了错误的变量,将变量更改为

@Input() items: any[];

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

编辑

使用最新的修改,将输入更改为 dropdownItems 后,父组件上的模板应调整为

<app-input-dropdown [dropdownItems]="items"></app-input-dropdown>

答案 1 :(得分:0)

在下拉菜单组件中似乎没有定义items。在您的ngOnInit中,您应该记录dropdownItems而不是ro将输入属性的名称重命名为items。同样在父HTML中,您应该使用[dropdownItems]=items

定义子组件

答案 2 :(得分:0)

由于您正在处理子组件和@Input(),因此我建议您执行以下操作:

@Component({
  selector: 'app-input-dropdown',
  templateUrl: './input-dropdown.component.html',
  styleUrls: ['./input-dropdown.component.scss'],
  encapsulation: ViewEncapsulation.None
})
export class InputDropdownComponent implements OnInit , OnChanges{

  @Input() dropdownItems: any[] = [];

  selectedItem: any;

  constructor(private el: ElementRef) { }

  ngOnChanges(changes : SimpleChanges){
   if(changes.dropdownItems.currentValue != undefined){
     console.log(changes.dropdownItems.currentValue);
     this.dropdownItems = changes.dropdownItems.currentValue ; // your dropdownItems will have data passed y component
         console.log(this.dropdownItems);  <------- won't be Undefined
    this.selectedItem = this.dropdownItems[0];

    const dropdownButton = this.el.nativeElement.querySelector('.dropdown-button');
    dropdownButton.classList.remove('dropdown-button');
    dropdownButton.classList.add('dropdown-input-button');
   }
  }

  ngOnInit() {    
  }

}

答案 3 :(得分:0)

您可能在父级中未定义distanceDropdownItems。请查看下面的链接,其中显示了一个示例,该示例使用Input装饰器将数据共享给孩子。

Share data from parent to child using Input decorator

如果没有,则在DOM中加载组件的方式可能会出现另一个问题。如果将子项放在父项之前的DOM中,则ngOnInit()调用仅在Init时第一次发生。这将导致您的输入在child中未定义。因此,您可以尝试实现ngOnChanges()来代替ngOnInit(),这将在父母加载和将数据传递给孩子的延迟时帮助从父母那里获取价值变化。

在父组件中使用*ngIf来延迟子组件的初始化。仅当必需的对象具有值时,才绑定子组件。

让我知道代码示例是否有帮助,我可以在这里分享。