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(){} угловой цикл жизненного цикла независимо от конструктора.

Это поможет вам. Приветствия.

Другие вопросы по тегам