Javascript Angular 2 组件@Input 不起作用

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/33326376/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 14:57:35  来源:igfitidea点击:

Angular 2 Component @Input not working

javascriptangulartypescript

提问by Zorthgo

I am stuck on trying to pass a property value into my component. From what I've read everything looks correct. But it is still not working. My test value gets output to the screen and the console as null. :(

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

This is my test component:

这是我的测试组件:

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

This is how I am calling the component from the parent page.

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

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

When the page render's the test value is empty. I only see 'Test Value :'.

当页面呈现时,测试值为空。我只看到“测试值:”。

Instead of 'Test Value : Blue32'.

而不是“测试值:Blue32”。

回答by Eric Martinez

You have four things that I can note :

你有四件事我可以注意:

  • You are passing an input in the root component, which will not work.
  • As @alexpods mentioned, you are using CamelCase. You should not.
  • You are passing an expression instead of an string through [test]. That means that angular2 is looking for a variable named Blue32instead of passing a raw string.
  • You are using the constructor. That will not work, it must be after the view has been initializeddata-bound properties have been initialized (see docs for OnInit).
  • 您正在根组件中传递一个输入,这将不起作用。
  • 正如@alexpods 提到的,您正在使用 CamelCase。你不应该。
  • 您正在通过一个表达式而不是一个字符串[test]。这意味着 angular2 正在寻找一个命名的变量,Blue32而不是传递一个原始字符串。
  • 您正在使用构造函数。那是行不通的,它必须在视图初始化之后数据绑定属性已经初始化(参见OnInit文档)。

So with a few fixes it should work

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

Example updated to beta 1

示例更新为 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);

See this plnkras an example.

以这个plnkr为例。

Update

更新

I see that people still reach this answer, so I've updated the plnkr to beta 1 and I corrected one point on the explanation : You can access inputs in ngAfterViewInit, but you can access them earlier in the lifecycle within ngOnInit.

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

回答by fgonzalez

It's that easy as surrounding the string with double quotes, like this:

就像用双引号将字符串括起来一样简单,如下所示:

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

回答by Mulperi

If you use brackets [] the Angular uses property binding and expects to receive an expressioninside the quotes and it looks for a property called 'Blue32' from your component class or a variable inside the template.

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

If you want to pass string as a value to the child component you can pass it like so:

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

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

or

或者

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

And then take it in to child.component.ts like this:

然后像这样把它放到 child.component.ts 中:

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

@Component({})
export class ChildComponent {

    @Input()
    childProperty: string;

}

回答by Charles HETIER

This angular class could make the trick for static attributes: ElementRefhttps://angular.io/docs/ts/latest/api/core/index/ElementRef-class.html

这个角度类可以为静态属性提供技巧: 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')
}

回答by Zorthgo

I believe that the problem here might have to do with the page's life cycle. Because inside the constructor the value of this.test is null. But if I add a button to the template linked to a function that pushes the value to the console (same as I am doing in the constructor) this.test will actually have a value.

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

回答by xameeramir

Sharing what worked for me:

分享对我有用的东西:

Adding an input to the Angular 4 app

向 Angular 4 应用程序添加输入

Assuming that we have 2 components:

假设我们有 2 个组件:

  • parent-component
  • child-component
  • parent-component
  • child-component

We wanted to pass some value from parent-componentto child-componenti.e. an @Inputfrom parent-component.htmlto child-component.ts. Below is an example which explains the implementation:

我们想从 to 传递一些值parent-componentchild-component@Inputparent-component.htmlto child-component.ts。下面是一个解释实现的例子:

parent-component.htmllooks like this:

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

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

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

parent-component.tslooks like this:

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

  
  class ParentComponent {

  someInputValue = 'Some Input Value';

}

child-component.htmllooks like this:

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

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

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

child-component.tslooks like this:

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

Notice that the value of the @Inputvalue is available inside ngOnInit()and not inside constructor().

请注意, value 的@Input值在 inside 中可用ngOnInit(),而在inside 中不可用constructor()

Objects reference behaviour in Angular 2 / 4

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

In Javascript, objects are stored as references.

在 Javascript 中,对象存储为引用

This exact behaviour can be re-produced with the help of Angular 2 / 4. Below is an example which explains the implementation:

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

parent-component.tslooks like this:

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

  
  class ParentComponent {

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

}

parent-component.htmllooks like this:

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

  
{{someInputValue.input}}



child-component.htmllooks like this:

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



Some Input Value {{someInputValue}}

change input

child-component.tslooks like this:

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

The function changeInput()will change the value of someInputValueinside both ChildComponent& ParentComponentbecause of their reference. Since, someInputValueis referenced from ParentComponent's someInputValueobject- the change in ChildComponent's someInputValueobjectchanges the value of ParentComponent's someInputValueobject. THIS IS NOT CORRECT. The references shall never be changed.

由于它们的引用,该函数changeInput()将更改&someInputValue内部的值。因为,从引用的对象-在变化的对象的值改变的对象这不正确。引用永远不会改变。ChildComponentParentComponentsomeInputValueParentComponentsomeInputValueChildComponentsomeInputValueParentComponentsomeInputValue

回答by jcmordan

Maybe look like a hammer, but you can put the input wrapped on an object like this:

也许看起来像一个锤子,但你可以把输入包裹在这样的对象上:

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

and change your class

并改变你的班级

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

回答by Mukesh

you have to import input like this at top of child component

您必须在子组件顶部导入这样的输入

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

回答by Sachin Mishra

When you are making use of @Input for the angular interaction.It is always preferred approach to pass the data from parent to child in JSON object apparently it doesn't not restrict by @Angular Team to use local variable or static variable.

当您使用@Input 进行角度交互时。显然,在 JSON 对象中将数据从父级传递给子级始终是首选方法,@Angular Team 并不限制使用局部变量或静态变量。

In context to access the value on child component make use ngOnInit(){} angular life hook cycleregardless of constructor.

在上下文中访问子组件上的值,无论构造函数如何,都使用ngOnInit(){} angular life hook cycle

That will help you out. Cheers.

那会帮助你。干杯。