Angular 2 组件 @Input 不工作
Angular 2 Component @Input not working
我一直在尝试将 属性 值传递到我的组件中。从我读过的内容来看,一切看起来都是正确的。但它仍然无法正常工作。我的测试值以 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>
页面呈现时测试值为空。我只看到 'Test Value :'.
而不是 'Test Value : Blue32'。
我认为这里的问题可能与页面的生命周期有关。因为在构造函数内部 this.test 的值为空。但是,如果我向模板添加一个按钮,该按钮链接到一个将值推送到控制台的函数(与我在构造函数中所做的相同),this.test 实际上会有一个值。
你有四点我可以注意到:
- 您正在根组件中传递输入,这将不起作用。
- 如@alexpods 所述,您正在使用 CamelCase。你不应该。
- 您正在通过
[test]
传递表达式而不是字符串。这意味着 angular2 正在寻找一个名为 Blue32
的变量,而不是传递原始字符串。
- 您正在使用构造函数。那是行不通的,它必须在
视图初始化之后 数据绑定属性已经初始化(参见 OnInit 的文档)。
所以通过一些修复它应该可以工作
示例更新到 beta 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.
这个 angular class 可以解决静态属性问题:
元素引用
https://angular.io/docs/ts/latest/api/core/index/ElementRef-class.html
import {ElementRef} from 'angular2/core'
constructor(elementRef: ElementRef) {
elementRef.nativeElement.getAttribute('api')
}
可能看起来像 锤子,但您可以像这样将输入包裹在一个物体上:
<TestCmp [test]='{color: 'Blue32'}'></TestCmp>
并更改您的 class
class ChildCmp {
@Input() test: any;
ngOnInit() {
console.log('This if the value for user-id: ' + this.test);
}
}
你必须在子组件的顶部像这样导入输入
import { Directive, Component, OnInit, Input } from '@angular/core';
当您为 angular 使用 @Input 时,interaction.It 始终是在 JSON 对象中将数据从父级传递给子级的首选方法,显然它不是@Angular 团队限制使用局部变量或静态变量。
在访问子组件上的值的上下文中,使用 ngOnInit(){} angular 生命挂钩循环 而不管构造函数。
这会帮助你。干杯。
Sharing what worked for me:
正在向 Angular 4 应用添加输入
假设我们有 2 个组件:
parent-component
child-component
我们想将一些值从 parent-component
传递到 child-component
,即从 parent-component.html
到 child-component.ts
的 @Input
。下面是一个解释实现的例子:
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
看起来像这样:
<p>Some Input Value {{someInputValue}}</p>
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()
将更改 ChildComponent
和 ParentComponent
中 someInputValue
的值,因为它们的引用。因为,someInputValue
引用自 ParentComponent
的 someInputValue
对象 - ChildComponent
的 someInputValue
object 更改 ParentComponent
的 someInputValue
object 的值。 这不正确。引用永远不会改变。
用双引号将字符串括起来就这么简单,就像这样:
<TestCmp [test]="'Blue32'"></TestCmp>
如果您使用方括号 [],则 Angular 使用 属性 绑定并期望在引号内接收 表达式 并查找 属性 从您的组件 class 或模板中的变量调用 '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;
}
当我遇到这个问题时,实际上只是一个编译错误,我必须先修复它(循环依赖需要解决)。
我一直在尝试将 属性 值传递到我的组件中。从我读过的内容来看,一切看起来都是正确的。但它仍然无法正常工作。我的测试值以 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>
页面呈现时测试值为空。我只看到 'Test Value :'.
而不是 'Test Value : Blue32'。
我认为这里的问题可能与页面的生命周期有关。因为在构造函数内部 this.test 的值为空。但是,如果我向模板添加一个按钮,该按钮链接到一个将值推送到控制台的函数(与我在构造函数中所做的相同),this.test 实际上会有一个值。
你有四点我可以注意到:
- 您正在根组件中传递输入,这将不起作用。
- 如@alexpods 所述,您正在使用 CamelCase。你不应该。
- 您正在通过
[test]
传递表达式而不是字符串。这意味着 angular2 正在寻找一个名为Blue32
的变量,而不是传递原始字符串。 - 您正在使用构造函数。那是行不通的,它必须在
视图初始化之后数据绑定属性已经初始化(参见 OnInit 的文档)。
所以通过一些修复它应该可以工作
示例更新到 beta 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.
这个 angular class 可以解决静态属性问题: 元素引用 https://angular.io/docs/ts/latest/api/core/index/ElementRef-class.html
import {ElementRef} from 'angular2/core'
constructor(elementRef: ElementRef) {
elementRef.nativeElement.getAttribute('api')
}
可能看起来像 锤子,但您可以像这样将输入包裹在一个物体上:
<TestCmp [test]='{color: 'Blue32'}'></TestCmp>
并更改您的 class
class ChildCmp {
@Input() test: any;
ngOnInit() {
console.log('This if the value for user-id: ' + this.test);
}
}
你必须在子组件的顶部像这样导入输入
import { Directive, Component, OnInit, Input } from '@angular/core';
当您为 angular 使用 @Input 时,interaction.It 始终是在 JSON 对象中将数据从父级传递给子级的首选方法,显然它不是@Angular 团队限制使用局部变量或静态变量。
在访问子组件上的值的上下文中,使用 ngOnInit(){} angular 生命挂钩循环 而不管构造函数。
这会帮助你。干杯。
Sharing what worked for me:
正在向 Angular 4 应用添加输入
假设我们有 2 个组件:
parent-component
child-component
我们想将一些值从 parent-component
传递到 child-component
,即从 parent-component.html
到 child-component.ts
的 @Input
。下面是一个解释实现的例子:
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
看起来像这样:
<p>Some Input Value {{someInputValue}}</p>
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()
将更改 ChildComponent
和 ParentComponent
中 someInputValue
的值,因为它们的引用。因为,someInputValue
引用自 ParentComponent
的 someInputValue
对象 - ChildComponent
的 someInputValue
object 更改 ParentComponent
的 someInputValue
object 的值。 这不正确。引用永远不会改变。
用双引号将字符串括起来就这么简单,就像这样:
<TestCmp [test]="'Blue32'"></TestCmp>
如果您使用方括号 [],则 Angular 使用 属性 绑定并期望在引号内接收 表达式 并查找 属性 从您的组件 class 或模板中的变量调用 '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;
}
当我遇到这个问题时,实际上只是一个编译错误,我必须先修复它(循环依赖需要解决)。