少し混乱しています。
次の簡単なディレクティブを参照してください。
@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
を使用しようとしているユーザーに絶対に疑問に思わないようにしたいのですが、角括弧[]
は常に存在する必要があります。彼らではないですか?
[]
を使用して@Input()
にバインドする場合、基本的にはテンプレート式です。
{{abc}}
を表示するのと同じ方法では何も表示されません(実際にabc
という変数がある場合を除く)。
文字列@Input()
があり、それを定数文字列にバインドしたい場合、次のようにバインドできます:[myText]=" 'some text' "
、または要するに、通常のHTML属性:myText="some text"
。
[myEnabled]="true"
が機能した理由は、true
が有効なテンプレート式であり、もちろんブール値true
に評価されるためです。
括弧は、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
あなたの混乱がどこから来ているのか理解できたと思います。 [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>
では、本質的に次のように言っています:
myDirective
をdiv要素に適用します。myEnabled
を右側の式にバインドします。式はtrue
と言うので、myEnabledの値はtrueです。myText
を右側の式にバインドします。式はabc
と言います。定義されたabcはありますか?いいえ、したがって式は未定義と評価されました。バインディング[]
はオブジェクト用で、それなしでは値は文字列です。型に注意してください。
コード内
<div [myDirective]="myDefaultText" [myEnabled]="true" [myText]="abc"></div>
オブジェクトをバインドしようとしましたが、オブジェクトが利用できないため、値はundefined
です。一方、バインディングを削除した場合、オブジェクトはなくなり、プロパティに割り当てられたstring
値のみになります。