Angular 2组件@Input无法正常工作

时间:2015-10-25 05:01:47

标签: javascript angular typescript

我一直试图将属性值传递给我的组件。从我所读到的一切看起来都是正确的。但它仍然无法正常工作。我的测试值输出到屏幕,控制台为null。 :(

这是我的测试组件:

import {Component, Input} from 'angular2/angular2';

@Component({
    selector: 'TestCmp',
    template: `Test Value : {{test}}`
})

export class TestCmp {

    @Input() test: string;

    constructor()
    {
        console.log('This if the value for user-id: ' + this.test);
    }
}

这就是我从父页面调用组件的方式。

<TestCmp [test]='Blue32'></TestCmp>

当页面呈现时,测试值为空。我只看到了测试值:&#39;。

取代&#39;测试价值:Blue32&#39;。

10 个答案:

答案 0 :(得分:123)

我有四件事可以注意到:

  • 您正在根组件中传递输入,这将无效。
  • 正如@alexpods所提到的,您使用的是CamelCase。你不应该。
  • 您正在通过[test]传递表达式而不是字符串。这意味着angular2正在寻找名为Blue32的变量,而不是传递原始字符串。
  • 您正在使用构造函数。这不起作用,必须在视图初始化之后初始化数据绑定属性(参见OnInit的文档)。

所以通过一些修复它应该可以工作

示例已更新为测试版1

import {Component, Input} from 'angular2/core';
import {bootstrap} from 'angular2/platform/browser';

@Component({
  selector : 'childcmp',
  template: `Test Value : {{test}}`
})
class ChildCmp {
    @Input() test: string;
    ngOnInit() {
        console.log('This if the value for user-id: ' + this.test);
    }
}

@Component({
    selector: 'testcmp',
    template : `<childcmp [test]="'Blue32'"></childcmp>`
    directives : [ChildCmp]
})
export class TestCmp {}

bootstrap(TestCmp);

请参阅此plnkr作为示例。

更新

我看到人们仍然得到了这个答案,所以我已经将plnkr更新为beta 1,我在解释中纠正了一点:您可以访问ngAfterViewInit中的输入,但您可以在生命周期的早期访问它们ngOnInit。

答案 1 :(得分:9)

用双引号包围字符串很简单,如下所示:

<TestCmp [test]="'Blue32'"></TestCmp>

答案 2 :(得分:6)

如果使用方括号[],Angular会使用属性绑定,并希望在引号内接收表达式,它会从组件类或模板中的变量中查找名为“Blue32”的属性

如果要将字符串作为值传递给子组件,可以像这样传递它:

<child-component childProperty='passing string'></child-component>

<child-component [childProperty]="'note double quotes'"></child-component>

然后把它带到像这样的child.component.ts:

import { Component, Input } from "@angular/core";

@Component({})
export class ChildComponent {

    @Input()
    childProperty: string;

}

答案 3 :(得分:5)

这个角度类可以成为静态属性的技巧: 的 ElementRef https://angular.io/docs/ts/latest/api/core/index/ElementRef-class.html

import {ElementRef} from 'angular2/core'

constructor(elementRef: ElementRef) {
    elementRef.nativeElement.getAttribute('api')
}

答案 4 :(得分:2)

我认为这里的问题可能与页面的生命周期有关。因为在构造函数中,this.test的值为null。但是如果我向模板添加一个按钮链接到一个将值推送到控制台的函数(就像我在构造函数中所做的那样),this.test实际上会有一个值。

答案 5 :(得分:1)

也许看起来像 hammer ,但你可以把输入包装在像这样的对象上:

<TestCmp [test]='{color: 'Blue32'}'></TestCmp>

并更改您的课程

class ChildCmp {
    @Input() test: any;
    ngOnInit() {
        console.log('This if the value for user-id: ' + this.test);
    }
}

答案 6 :(得分:1)

你必须在子组件

的顶部导入这样的输入
import { Directive, Component, OnInit, Input } from '@angular/core';

答案 7 :(得分:1)

  

分享对我有用的东西:

向Angular 4应用添加输入

假设我们有两个组成部分:

  • parent-component
  • child-component

我们希望将parent-component的某些值传递给child-component,即@Inputparent-component.html传递到child-component.ts。以下是解释实施的示例:

parent-component.html看起来像这样:

<child-component [someInputValue]="someInputValue"></child-component>

parent-component.ts看起来像这样:

  
  class ParentComponent {

  someInputValue = 'Some Input Value';

}

child-component.html看起来像这样:

<p>Some Input Value {{someInputValue}}</p>

child-component.ts看起来像这样:


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

@Component({
  selector: 'child-component',
  templateUrl: './child-component.html'
})
export class ChildComponent implements OnInit {

  @Input() someInputValue: String = "Some default value";

  @Input()
  set setSomeInputValue(val) {
    this.someInputValue += " modified";
  }

  constructor() {
    console.log('someInputValue in constructor ************** ', this.someInputValue); //someInputValue in constructor ************** undefined
  }

  ngOnInit() {
    console.log('someInputValue  in ngOnInit ************** ', this.someInputValue); //someInputValue  in ngOnInit ************** Some Input Value
  }
}

请注意@Input值的值在ngOnInit()内,而不在constructor()内。

Angular 2/4中的对象引用行为

在Javascript中,对象存储为references

这个确切的行为可以在Angular 2/4的帮助下重新生成。下面是一个解释实现的例子:

parent-component.ts看起来像这样:

  
  class ParentComponent {

  someInputValue = {input: 'Some Input Value'};

}

parent-component.html看起来像这样:

  
{{someInputValue.input}}



child-component.html看起来像这样:



Some Input Value {{someInputValue}}

change input

child-component.ts看起来像这样:


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

@Component({
  selector: 'child-component',
  templateUrl: './child-component.html'
})
export class ChildComponent implements OnInit {

  @Input() someInputValue = {input:"Some default value"};

  @Input()
  set setSomeInputValue(val) {
    this.someInputValue.input += " set from setter";
  }

  constructor() {
    console.log('someInputValue in constructor ************** ', this.someInputValue); //someInputValue in constructor ************** undefined
  }

  ngOnInit() {
    console.log('someInputValue  in ngOnInit ************** ', this.someInputValue); //someInputValue  in ngOnInit ************** Some Input Value
  }

  changeInput(){
    this.someInputValue.input += " changed";
  }
}

函数changeInput()将更改someInputValueChildComponentParentComponent的值。 someInputValue因为他们的参考。由于ParentComponent引用了someInputValue的{​​{1}} 对象,因此ChildComponent的{​​{1}} 对象发生了变化更改了someInputValue的{​​{1}} 对象的值。 这不正确。参考不得改变。

答案 8 :(得分:0)

当你使用@Input进行角度交互时。总是首选的方法将数据从父对象传递到JSON对象中,显然它不受@Angular Team限制使用局部变量或静态变量

在访问子组件的值的上下文中,无论构造函数如何,都使用 ngOnInit(){}角度生命挂钩循环

那会帮助你。欢呼声。

答案 9 :(得分:0)

当我遇到这个问题时,实际上只有一个编译错误,我必须首先解决(循环依赖需要解决)。