web-dev-qa-db-fra.com

Angular 2 Le composant @Input ne fonctionne pas

Je suis coincé pour essayer de transmettre une valeur de propriété à mon composant. D'après ce que j'ai lu, tout semble correct. Mais cela ne fonctionne toujours pas. Ma valeur de test est affichée à l'écran et à la console sous la forme null. :(

Ceci est mon composant de test:

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

Voici comment j'appelle le composant à partir de la page parent.

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

Lorsque la page rend la valeur de test est vide. Je ne vois que 'Test Value:'.

Au lieu de 'Test Value: Blue32'.

68
Zorthgo

Vous avez quatre choses que je peux noter:

  • Vous passez une entrée dans le composant racine, ce qui ne fonctionnera pas.
  • Comme @alexpods l'a mentionné, vous utilisez CamelCase. Tu ne devrais pas.
  • Vous transmettez une expression au lieu d'une chaîne via [test]. Cela signifie que angular2 recherche une variable nommée Blue32 au lieu de transmettre une chaîne brute.
  • Vous utilisez le constructeur. Cela ne fonctionnera pas, il doit être après la la vue a été initialisée les propriétés liées aux données ont été initialisées (voir la documentation de OnInit ).

Donc, avec quelques corrections, cela devrait fonctionner

Exemple mis à jour vers la version bêta 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);

Voir ceci plnkr à titre d'exemple.

Mise à jour

Je vois que les gens parviennent toujours à cette réponse. J'ai donc mis à jour la commande plnkr vers la version bêta 1 et j'ai corrigé un point de l'explication: vous pouvez accéder aux entrées dans ngAfterViewInit, mais vous pouvez y accéder plus tôt dans le cycle de vie de ngOnInit.

127
Eric Martinez

C'est aussi simple que d'entourer la chaîne de guillemets, comme ceci:

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

Si vous utilisez des crochets [], la Angular utilise la liaison de propriété et s'attend à recevoir une expression entre guillemets et recherche une propriété appelée "Blue32" dans votre classe de composant ou une variable. à l'intérieur du modèle.

Si vous voulez transmettre chaîne en tant que valeur au composant enfant, vous pouvez le transmettre comme suit:

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

ou

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

Et puis prenez-le dans child.component.ts comme ceci:

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

@Component({})
export class ChildComponent {

    @Input()
    childProperty: string;

}
6
Mulperi

Cette classe angular pourrait faire l'affaire des attributs statiques: 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')
}
5
Charles HETIER

Je crois que le problème ici pourrait avoir à faire avec le cycle de vie de la page. Parce qu'à l'intérieur du constructeur, la valeur de this.test est null. Mais si j'ajoute un bouton au modèle lié à une fonction qui transmet la valeur à la console (comme je le fais dans le constructeur) this.test aura en fait une valeur.

2
Zorthgo

Partager ce qui a fonctionné pour moi:

Ajout d'une entrée à l'application Angular 4

En supposant que nous ayons 2 composants:

  • parent-component
  • child-component

Nous voulions passer une valeur de parent-component à child-component c'est-à-dire un @Input de parent-component.html à child-component.ts. Voici un exemple qui explique la mise en œuvre:

parent-component.html ressemble à ceci:

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

parent-component.ts ressemble à ceci:

  
  class ParentComponent {

  someInputValue = 'Some Input Value';

}

child-component.html ressemble à ceci:

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

child-component.ts ressemble à ceci:


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

Notez que la valeur de @Input est disponible dans ngOnInit() et non dans constructor().

Comportement de référence des objets dans Angular 2/4

En Javascript, les objets sont stockés sous la forme références .

Ce comportement exact peut être reproduit à l'aide de Angular 2/4. Vous trouverez ci-dessous un exemple qui explique la mise en oeuvre:

parent-component.ts ressemble à ceci:

  
  class ParentComponent {

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

}

parent-component.html ressemble à ceci:

  
{{someInputValue.input}}



child-component.html ressemble à ceci:


Some Input Value {{someInputValue}}

change input

child-component.ts ressemble à ceci:


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

La fonction changeInput() modifiera la valeur de someInputValue dans les deux ChildComponent & ParentComponent en raison de leur référence. Depuis, someInputValue est référencé à partir de ParentComponent 's someInputValue object - la modification de ChildComponent' s someInputValue object modifie la valeur de ParentComponent 's someInputValue object . CE IS PAS CORRECT . Les références ne doivent jamais être changées.

1
student

vous devez importer une entrée comme celle-ci en haut du composant enfant

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

Peut-être que cela ressemble à un martea, mais vous pouvez placer l'entrée encapsulée sur un objet comme celui-ci:

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

et change de classe

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

Lorsque vous utilisez @Input pour l'interaction angular, il est toujours préférable de transmettre les données d'un parent à un enfant dans un objet JSON. Apparemment, @Angular Team n'interdit apparemment pas l'utilisation de variable locale. ou variable statique.

Dans le contexte pour accéder à la valeur du composant enfant, utilisez ngOnInit () {} angular cycle de vie quel que soit le constructeur.

Cela vous aidera. À votre santé.

0
Sachin Mishra