Angular 2 Component @Input funktioniert nicht

74

Ich versuche nicht, einen Eigenschaftswert an meine Komponente zu übergeben. Nach dem, was ich gelesen habe, sieht alles richtig aus. Aber es funktioniert immer noch nicht. Mein Testwert wird als Null auf dem Bildschirm und der Konsole ausgegeben. :(

Dies ist meine Testkomponente:

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

So rufe ich die Komponente von der übergeordneten Seite aus auf.

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

Wenn die Seite gerendert wird, ist der Testwert leer. Ich sehe nur 'Testwert:'.

Anstelle von 'Testwert: Blue32'.

Zorthgo
quelle
3
Verwenden Sie keine CamelCase-Namen in Vorlagen. Bei HTML wird die Groß- und Kleinschreibung nicht berücksichtigt.
Alexpods
Danke alex! Ich denke, ich muss diesen Habbit ändern. ; 0)
Zorthgo

Antworten:

136

Sie haben vier Dinge, die ich beachten kann:

  • Sie übergeben eine Eingabe in der Stammkomponente, die nicht funktioniert.
  • Wie bereits bei @alexpods erwähnt, verwenden Sie CamelCase. Du solltest nicht.
  • Sie übergeben einen Ausdruck anstelle einer Zeichenfolge [test]. Das bedeutet, dass angle2 nach einer Variablen mit dem Namen sucht, Blue32anstatt eine Rohzeichenfolge zu übergeben.
  • Sie verwenden den Konstruktor. Das wird nicht funktionieren, es muss sein, nachdem die Ansicht initialisiert wurde. Datengebundene Eigenschaften wurden initialisiert (siehe Dokumente für OnInit ).

Mit ein paar Korrekturen sollte es also funktionieren

Beispiel auf Beta 1 aktualisiert

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

Sehen Sie sich dieses Beispiel als Beispiel an.

Aktualisieren

Ich sehe, dass die Leute diese Antwort immer noch erreichen, also habe ich das plnkr auf Beta 1 aktualisiert und einen Punkt in der Erklärung korrigiert: Sie können auf Eingaben in ngAfterViewInit zugreifen, aber Sie können früher im Lebenszyklus in ngOnInit darauf zugreifen.

Eric Martinez
quelle
1
Danke Eric für die Hilfe! ... Das sind einige sehr gute Punkte. "AfterViewInit" wird wirklich nützlich sein. :)
Zorthgo
Dieser Plunkr scheint kaputt zu sein, ich sehe nur "Test Value:" auf dem neuesten Chrome / Firefox.
Aikeru
1
@aikeru danke, dass du mich informiert hast. Das ist wirklich komisch, der plnkr sah kaum aus wie der Code in der Antwort. Wie auch immer, ich habe es behoben :)
Eric Martinez
5
Es ist PascalCase, nicht camelCase.
Elfayer
4
Für alle anderen war der Teil dieser Lösung, der dies für mich behoben hat, die Verwendung <childcmp [test]="'Blue32'">von <childcmp [test]="Blue32">(der doppelt zitierten Sache)
FirstDivision
14

So einfach ist es, die Zeichenfolge mit doppelten Anführungszeichen zu umgeben:

<TestCmp [test]="'Blue32'"></TestCmp>
fgonzalez
quelle
6

Wenn Sie Klammern [] verwenden, verwendet Angular die Eigenschaftsbindung und erwartet, dass in den Anführungszeichen ein Ausdruck angezeigt wird. Er sucht nach einer Eigenschaft namens 'Blue32' aus Ihrer Komponentenklasse oder nach einer Variablen in der Vorlage.

Wenn Sie eine Zeichenfolge als Wert an die untergeordnete Komponente übergeben möchten, können Sie sie folgendermaßen übergeben:

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

oder

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

Und nehmen Sie es dann wie folgt in child.component.ts auf:

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

@Component({})
export class ChildComponent {

    @Input()
    childProperty: string;

}
Mulperi
quelle
5

Diese Winkelklasse könnte den Trick für statische Attribute machen: 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')
}
Charles HETIER
quelle
Das habe ich gesucht. Du bist der Retter Charles!
Gautam1168
danke gautam1168. Ich habe das Problem mit dem Ablauf des Links behoben
Charles HETIER
2

Ich glaube, dass das Problem hier möglicherweise mit dem Lebenszyklus der Seite zu tun hat. Weil im Konstruktor der Wert von this.test null ist. Wenn ich jedoch der Vorlage eine Schaltfläche hinzufüge, die mit einer Funktion verknüpft ist, die den Wert an die Konsole überträgt (wie im Konstruktor), hat dieser Test tatsächlich einen Wert.

Zorthgo
quelle
2

Teilen, was für mich funktioniert hat:

Hinzufügen einer Eingabe zur Angular 4-App

Angenommen, wir haben 2 Komponenten:

  • parent-component
  • child-component

Wir wollten einen Wert von parent-componentbis übergeben, child-componentdh einen @Inputvon parent-component.htmlbis child-component.ts. Unten finden Sie ein Beispiel, das die Implementierung erklärt:

parent-component.html sieht aus wie das:

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

parent-component.ts sieht aus wie das:

  
  class ParentComponent {

  someInputValue = 'Some Input Value';

}

child-component.html sieht aus wie das:

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

child-component.ts sieht aus wie das:


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

Beachten Sie, dass der Wert des @InputWerts innerhalb ngOnInit()und nicht innerhalb verfügbar ist constructor().

Objektreferenzverhalten in Angular 2/4

In Javascript werden Objekte als Referenzen gespeichert .

Dieses genaue Verhalten kann mit Hilfe von Angular 2/4 wiederhergestellt werden. Nachfolgend finden Sie ein Beispiel, das die Implementierung erklärt:

parent-component.ts sieht aus wie das:

  
  class ParentComponent {

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

}

parent-component.html sieht aus wie das:

  
{{someInputValue.input}}



child-component.html sieht aus wie das:



Some Input Value {{someInputValue}}

change input

child-component.ts sieht aus wie das:


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

Die Funktion changeInput()ändert den Wert von someInputValueinside sowohl ChildComponent& ParentComponentaufgrund ihrer Referenz. Da someInputValueaus verwiesen wird ParentComponent‚s someInputValue Objekt - die Änderung in ChildComponent‘ s - someInputValue Objekt ändert den Wert von ParentComponent‚s - someInputValue Objekt . Dies ist nicht richtig . Die Referenzen dürfen niemals geändert werden.

Zameer Ansari
quelle
1

Sieht vielleicht aus wie ein Hammer , aber Sie können die Eingabe auf ein Objekt wie das folgende setzen:

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

und ändern Sie Ihre Klasse

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

Sie müssen Eingaben wie diese oben in die untergeordnete Komponente importieren

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

Wenn Sie @Input für die Winkelinteraktion verwenden. Es ist immer ein bevorzugter Ansatz, die Daten im JSON-Objekt vom übergeordneten zum untergeordneten Element zu übergeben. Anscheinend wird die Verwendung lokaler Variablen oder statischer Variablen durch @Angular Team nicht eingeschränkt.

Verwenden Sie im Kontext ngOnInit () {} den Winkellebenszyklus-Hook-Zyklus, um auf den Wert für die untergeordnete Komponente zuzugreifen, unabhängig vom Konstruktor.

Das wird dir helfen. Prost.

Sachin Mishra
quelle
0

Als ich dieses Problem hatte, gab es tatsächlich nur einen Kompilierungsfehler, den ich zuerst beheben musste (zirkuläre Abhängigkeit muss behoben werden).

James L.
quelle