web-dev-qa-db-fra.com

Quand utiliser les crochets [] dans les directives @Inputs et quand non?

Je suis un peu confus.

Voir cette directive simple:

 @Directive({
      selector: '[myDirective]'
    })
    export class MyDirective {

      private text: string;
      private enabled: boolean;

      @Input() myDirective:string;

      @Input('myText')
      set myText(val: string) {
        this.text = val;
      }

      @Input('myEnabled')
      set myEnabled(val: boolean) {
        this.enabled = val;
      }

      ngOnInit() {

        console.log("myDirective string: " + this.myDirective);
        console.log("myText string: " + this.text); 
        console.log("myEnabled boolean: " + this.enabled);
    }
}

si mon html ressemblera à ceci:

<div [myDirective]="myDefaultText" [myEnabled]="true"  [myText]="abc"></div>

La sortie sera:

myDirective string: myDefaultText real value  // good
myEnabled boolean: true                       // good
myText string: undefined                      // Why?

Si je RETIRE le [] de myText:

<div [myDirective]="myDefaultText" [myEnabled]="true"  myText="abc"></div>

La sortie sera:

myDirective string: myDefaultText real value  // good
myEnabled boolean: true                       // good
myText string: abc                            // GOOD

Je peux aussi enlever le [] de myEnabled et cela fonctionnera aussi. Donc, voici ma confusion - quand je dois utiliser des crochets [] et quand ce n’est pas le cas, même si je veux que l’utilisateur qui va utiliser myDirective ne se demandera jamais si ou non, je pense que les crochets [] devrait toujours être là. N'est-ce pas?

40
AngularOne

Lorsque vous utilisez [] Pour vous lier à une @Input(), il s'agit essentiellement d'une expression de modèle.

De la même manière, afficher {{abc}} Ne ferait rien (sauf si vous aviez réellement une variable appelée abc).

Si vous avez une chaîne @Input() et que vous souhaitez la lier à une chaîne constante, vous pouvez la lier comme suit: [myText]=" 'some text' " Ou, en bref, comme un attribut HTML normal: myText="some text".

La raison pour laquelle [myEnabled]="true" A fonctionné est que true est une expression de modèle valide qui, bien sûr, a pour résultat le booléen true.

28
Amit

Les crochets indiquent à Angular d'évaluer l'expression du modèle. Si vous omettez les crochets, Angular considère la chaîne comme une constante et initialise la propriété target avec cette chaîne. Il n'évalue pas la chaîne!

Ne commettez pas l'erreur suivante:

    <!-- ERROR: HeroDetailComponent.hero expects a
         Hero object, not the string "currentHero" -->
    <hero-detail hero="currentHero"></hero-detail>

vérifier: https://angular.io/docs/ts/latest/guide/template-syntax.html#!#property-binding

9
sainu

Je pense que je comprends d'où vient votre confusion. Lorsque vous dites [myText]="abc", Vous vous attendez à ce que myText soit une propriété définie dans mon composant dont la valeur que je souhaite initialiser à abc. Mais ce n'est pas correct. Mais d’abord, comprenons un peu plus le langage HTML.

En HTML, vous pouvez définir un élément comme celui-ci.

<input type="text" value="Bob">

input est un élément dont attributes est un type et une valeur. Lorsque votre navigateur analyse cela, il crée une entrée DOM (un objet) pour cet élément. L'entrée du DOM aura properties comme align, baseURI, childNodes, enfants, etc. C'est donc la différence entre les attributs HTML et les propriétés du DOM Voir la référence . Parfois, l'attribut et la propriété ont les mêmes noms, ce qui entraîne une confusion. Pour la balise d’entrée ci-dessus, elle a l’attribut value = Bob et une propriété value qui aura la valeur de ce que vous tapez dans la zone de texte. En résumé, attribut correspond à ce que vous définissez à propos de la balise et la propriété correspond à ce qui est généré dans l'arborescence DOM.

Vous devez savoir que c'est parce que, dans le monde angulaire, le seul rôle des attributs est d'initialiser l'état de l'élément et de la directive. Lorsque vous écrivez une liaison de données, vous traitez exclusivement avec les propriétés et les événements de l'objet cible. Les attributs HTML disparaissent effectivement.

Tout ce que cela signifie, c'est que si vous écrivez <img [src]="heroImageUrl">, Cela signifie que src n'est PAS un attribut, mais un property défini dans le DOM de img. Et le membre de droite heroImageUrl est une expression de modèle.

La simple différence entre [myText]="abc" Et myText="abc" Est que vous demandez précédemment à angular de définir PROPERTY myText, où vous créez dans ce dernier un ATTRIBUTE appelé myText. avoir sa propre propriété DOM. Angular ne traite pas d'attributs.

Donc, pour résumer, dans <div [myDirective]="myDefaultText" [myEnabled]="true" [myText]="abc"></div>, Vous dites essentiellement que:

  1. applique la directive myDirective à mon élément div.
  2. lie la variable myEnabled à l'expression de droite. L'expression dit true, la valeur de myEnabled est donc true.
  3. lie la variable myText à l'expression de droite. L'expression dit abc. Y a-t-il un abc défini? Non, l'expression est évaluée à indéfinie.
6
Rash

contraignant [] est pour les objets, sans cela la valeur est string. Attention aux types.

Dans le code

<div [myDirective]="myDefaultText" [myEnabled]="true"  [myText]="abc"></div>

vous avez essayé de lier l'objet, mais celui-ci n'est pas disponible; sa valeur est donc undefined. D'un autre côté, si vous supprimez la liaison, alors l'objet est parti, vous n'avez qu'une valeur string attribuée à la propriété.

5
Roman C