Angular 2 Component @Input не работает
Я застрял при попытке передать значение свойства в мой компонент. Из того, что я прочитал, все выглядит правильно. Но это все еще не работает. Мое тестовое значение выводится на экран и консоль как ноль.:(
Это мой тестовый компонент:
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:".
Вместо "Тестовое значение: Blue32".
9 ответов
У меня есть четыре вещи, которые я могу отметить:
- Вы передаете вход в корневой компонент, который не будет работать.
- Как уже упоминалось @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 до бета-версии 1, и я исправил один пункт в объяснении: вы можете получить доступ к входам в ngAfterViewInit, но вы можете получить доступ к ним ранее в жизненном цикле в ngOnInit.
Это так просто, как заключить строку в двойные кавычки, например так:
<TestCmp [test]="'Blue32'"></TestCmp>
Если вы хотите передать строку как значение дочернему компоненту, вы можете передать ее следующим образом:
<child-component [childProperty]="'note double quotes'"></child-component>
А затем перенесите его в child.component.ts следующим образом:
import { Component, Input } from "@angular/core";
@Component({})
export class ChildComponent {
@Input()
valueComing: string;
}
Этот угловой класс может сделать трюк для статических атрибутов: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')
}
Поделиться тем, что сработало для меня:
Добавление входа в приложение Angular 4
Предполагая, что у нас есть 2 компонента:
parent-component
child-component
Мы хотели передать некоторую ценность из parent-component
в child-component
то есть @Input
от parent-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 объекты хранятся в виде ссылок.
Это точное поведение может быть воспроизведено с помощью 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()
изменит значение someInputValue
внутри обоих ChildComponent
& ParentComponent
из-за их ссылки. Поскольку, someInputValue
ссылка из ParentComponent
"s someInputValue
объект - изменение в ChildComponent
"s someInputValue
объект меняет значение ParentComponent
"s someInputValue
объект. ЭТО НЕ ПРАВИЛЬНО. Ссылки никогда не должны быть изменены.
Я считаю, что проблема здесь может быть связана с жизненным циклом страницы. Потому что внутри конструктора значение this.test равно нулю. Но если я добавлю кнопку в шаблон, связанный с функцией, которая помещает значение в консоль (так же, как я делаю это в конструкторе), this.test действительно будет иметь значение.
Вы должны импортировать ввод, как это в верхней части дочернего компонента
import { Directive, Component, OnInit, Input } from '@angular/core';
Может быть, это похоже на молоток, но вы можете поместить ввод, обернутый в объект следующим образом:
<TestCmp [test]='{color: 'Blue32'}'></TestCmp>
и измени свой класс
class ChildCmp {
@Input() test: any;
ngOnInit() {
console.log('This if the value for user-id: ' + this.test);
}
}
Когда у меня возникла эта проблема, на самом деле была просто ошибка компиляции, которую я должен был исправить в первую очередь (необходимо разрешить круговую зависимость).
Когда вы используете @Input для углового взаимодействия. Это всегда предпочтительный подход для передачи данных от родителя к потомку в объекте JSON, очевидно, @Angular Team не ограничивает использование локальной или статической переменной.
В контексте доступа к значению на дочернем компоненте используйте ngOnInit(){} угловой цикл жизненного цикла независимо от конструктора.
Это поможет вам. Приветствия.