web-dev-qa-db-ja.com

ディレクティブ@Inputsで角括弧[]を使用する場合と使用しない場合

少し混乱しています。

次の簡単なディレクティブを参照してください。

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

私のhtmlが次のようになる場合:

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

出力は次のようになります。

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

myTextから[]を削除した場合:

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

出力は次のようになります。

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

myEnabledから[]を削除することもできます。これも機能します。だからここに私の混乱があります-角括弧[]を使用する必要があるときとそうでないとき、myDirectiveを使用しようとしているユーザーに絶対に疑問に思わないようにしたいのですが、角括弧[]は常に存在する必要があります。彼らではないですか?

40
AngularOne

[]を使用して@Input()にバインドする場合、基本的にはテンプレート式です。

{{abc}}を表示するのと同じ方法では何も表示されません(実際にabcという変数がある場合を除く)。

文字列@Input()があり、それを定数文字列にバインドしたい場合、次のようにバインドできます:[myText]=" 'some text' "、または要するに、通常のHTML属性:myText="some text"

[myEnabled]="true"が機能した理由は、trueが有効なテンプレート式であり、もちろんブール値trueに評価されるためです。

28
Amit

括弧は、Angularにテンプレート式を評価するように指示します。角かっこを省略すると、Angularは文字列を定数として扱い、その文字列でターゲットプロパティを初期化します。文字列を評価しません!

次の間違いをしないでください。

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

チェック: https://angular.io/docs/ts/latest/guide/template-syntax.html#!#property-binding

9
sainu

あなたの混乱がどこから来ているのか理解できたと思います。 [myText]="abc"と言うとき、myTextはコンポーネントで定義されたプロパティであり、その値はabcに初期化する必要があります。しかし、これは正しくありません。しかし、最初に、HTMLについてもう少し理解しましょう。

HTMLでは、このような要素を定義できます。

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

inputは、attributesがタイプと値である要素です。ブラウザがこれを解析すると、この要素のDOMエントリ(オブジェクト)が作成されます。 DOMエントリには、align、baseURI、childNodes、childrenなどのpropertiesがいくつかあります。したがって、これがHTML属性とDOMプロパティの違いです 参照を参照 。時々、属性とプロパティは同じ名前を持ち、混乱を引き起こします。上記の入力タグの場合、属性はvalue = Bobであり、プロパティvalueもあります。このプロパティは、テキストボックスに入力した値を保持します。要約すると、属性はタグについて定義するものであり、プロパティはDOMツリーで生成されるものです。

これを知る必要がある理由は、Angularの世界では、属性の唯一の役割は要素とディレクティブの状態を初期化することだからです。データバインディングを記述する場合、ターゲットオブジェクトのプロパティとイベントのみを処理します。 HTML属性は事実上消えます。

つまり、<img [src]="heroImageUrl">と記述すると、srcは属性ではなく、imgのDOM内で定義されたpropertyであることを意味します。そして、右側のheroImageUrlはテンプレート式です。

[myText]="abc"myText="abc"の単純な違いは、前者ではangularにPROPERTY myTextを設定するように求めていることです。後者ではmyTextという属性を作成し、この属性は独自のDOMプロパティがあります。 Angularは属性を処理しません。

要約すると、<div [myDirective]="myDefaultText" [myEnabled]="true" [myText]="abc"></div>では、本質的に次のように言っています:

  1. ディレクティブmyDirectiveをdiv要素に適用します。
  2. 変数myEnabledを右側の式にバインドします。式はtrueと言うので、myEnabledの値はtrueです。
  3. 変数myTextを右側の式にバインドします。式はabcと言います。定義されたabcはありますか?いいえ、したがって式は未定義と評価されました。
6
Rash

バインディング[]はオブジェクト用で、それなしでは値は文字列です。型に注意してください。

コード内

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

オブジェクトをバインドしようとしましたが、オブジェクトが利用できないため、値はundefinedです。一方、バインディングを削除した場合、オブジェクトはなくなり、プロパティに割り当てられたstring値のみになります。

5
Roman C