Angular 2 Component @Input не працює


75

Я застряг у спробі передати значення властивості у свій компонент. З прочитаного все виглядає правильно. Але це все ще не працює. Моє тестове значення отримує вихід на екран та консоль як нульовий. :(

Це мій компонент тесту:

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>

Коли візуалізація сторінки, тестове значення порожнє. Я бачу лише "Значення тесту:".

Замість "Тестове значення: Blue32".


3
Не використовуйте імена CamelCase у шаблонах. HTML не враховує регістр.
alexpods

Дякую Алекс! Думаю, мені доведеться змінити цю звичку. ; 0)
Зортго,

Відповіді:


139

У вас є чотири речі, які я можу зазначити:

  • Ви передаєте вхідні дані в кореневий компонент, що не буде працювати.
  • Як згадував @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.


1
Дякую Еріку за допомогу! ... Це дуже хороші моменти. "AfterViewInit" дійсно стане в нагоді. :)
Zorthgo,

Цей plunkr здається зламаним, я бачу лише "Тестове значення:" в останньому Chrome / Firefox.
Айкеру,

1
@aikeru дякую, що повідомили мене. Це справді дивно, plnkr ледь виглядав як код у відповіді. У будь-якому разі, я це виправив :)
Ерік Мартінес

5
Це PascalCase, а не camelCase.
Elfayer

4
Для когось іншого частина цього рішення, яка це виправила для мене, використовувала <childcmp [test]="'Blue32'">замість <childcmp [test]="Blue32">(подвійне цитування)
FirstDivision 02.03.17

15

Це так просто, як оточити рядок подвійними лапками, наприклад:

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

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;

}

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

Це те, що я шукав. Ти спаситель Чарльз!
gautam1168

дякую gautam1168. Я виправив проблему закінчення терміну дії посилання
Charles HETIER

2

Я вважаю, що проблема тут може бути пов’язана із життєвим циклом сторінки. Оскільки всередині конструктора значення this.test є нульовим. Але якщо я додаю кнопку до шаблону, зв’язану з функцією, яка штовхає значення на консоль (те саме, що я роблю в конструкторі), this.test насправді матиме значення.


2

Поділитися тим, що мені вдалося:

Додавання вхідних даних до програми 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 об'єкта . ЦЕ НЕ ПРАВИЛЬНО . Посилання ніколи не змінюються.


1

Можливо, схожий на молоток , але ви можете покласти введення, загорнуте на такий об’єкт:

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

і змінити свій клас

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

1

вам потрібно імпортувати введення, як це, у верхній частині дочірнього компонента

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

0

Коли ви використовуєте @Input для кутової взаємодії. Завжди є кращим підходом передавати дані від батьків дочірньому об'єкту JSON, мабуть, це не обмежує команда @Angular використовувати локальну змінну або статичну змінну.

У контексті доступу до значення дочірнього компонента використовуйте ngOnInit () {} кутовий життєвий цикл підключення незалежно від конструктора.

Це вам допоможе. Ура.


0

Коли у мене виникла ця проблема, насправді була просто помилка компіляції, яку мені довелося виправити спочатку (циркулярна залежність потребувала вирішення).

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.