この記事は機械翻訳のミラー記事です。元の記事にジャンプするにはこちらをクリックしてください。

眺める: 15833|答える: 1

[角] Angular開発チュートリアル:ng-contentを用いたコンポーネントコンテンツ投影

[リンクをコピー]
掲載地 2019/06/12 10:14:39 | | | |
Angularでは、コンポーネントは特別な指令であり、その特別な特徴は独自のテンプレート(html)とスタイル(css)を持つことです。 したがって、コンポーネントを使うことでコードを高度にデカップリングし、再利用可能で、簡単に拡張できます。 通常の成分は次のように定義されます。

demo.component.ts:


demo.component.html:


demo.component.scss:

コンポーネントを参照すると、解析されたコンテンツが次のように描画されます:



外部から投影されたコンテンツを受け入れる必要がある場合、つまり定義する以上の内容を提示することになるとします。 本記事の主人公を招待しますng-content(ng-content)

単純投影

まずは最も簡単なものから始めましょう。修正したdemo.component.htmlとdemo.component.scssをdemo.component.htmlに追加します。以下の通りです:

demo.component.html:

demo.component.scss:

効果のために、容器の背景色は意図的にオレンジ色に定義されています。

この時点でコンポーネントを参照する際に外部からコンテンツをキャストでき、外部コンテンツはオレンジ色の領域に表示されます。



ターゲット投影

もし複数のコンテンツが同時に存在した場合、外部コンテンツはどのように投影されるのでしょうか?

まずは例を見てみましょう。区別のために青い領域、修正されたdemo.component.html、そしてdemo.component.scssを追加しました。

demo.component.html:

demo.component.scss:

コンポーネントを参照すると:

この時点で、外部コンテンツが青い領域に投影されているのがわかります:



もちろん、青いエリアコードの後にオレンジのエリアコードを置くと、外部コンテンツはオレンジのエリアに投影されます:



上記の例から、もし単純な も存在すれば、外部コンテンツはコンポーネントテンプレートの最後の一つに投影されることがわかります。

この問題を知っていると、外部コンテンツをターゲットを絞って投影できるのか疑問に思うかもしれません。 答えは明らかにイエスです。

これに対処するために、1つを応援してください選ぶ特定の場所に特定のコンテンツを投影できる属性です。 このプロパティはCSSセレクタ(タグセレクタ、クラスセレクタ、属性セレクタ)をサポートしています、... )あなたの望むものに合わせて。 ng-contentにselect属性が設定されていなければ、完全なコンテンツ、または他のng-content要素と一致しないコンテンツを受け取ります。

例を直接見ると、修正された demo.component.html と demo.component.scss は以下の通りです。

demo.component.html:

demo.component.scss:

上記のコードからわかるように、青いエリアはタグヘッダーの一部を受け取り、赤いエリアはクラス「demo2」のdiv部分を受け取り、緑のエリアはプロパティ名「demo3」のdiv部分を受け取り、オレンジのエリアは残りの外部コンテンツ(start、i is the content of the external embed、終了)を受け取ります。

コンポーネントを参照すると:



この時点で、外部コンテンツが指定された に投影されるのが見えます。

知識の拡大

ngProjectAs

ここで、ng-contentのselectプロパティにより外部コンテンツを与えられた に投影することを指定できることがわかりました。

select属性に基づいてコンテンツを正しく投影するには制限があります。タグヘッダーであれ、クラス「demo2」のdivであれ、プロパティ名が「demo3」であれ、これらのタグはすべてコンポーネントタグの直接的なサブノードです。

もし直接のサブノードでなければどうなっていたでしょうか? デモコンポーネントを参照するコードを単純に修正し、タグヘッダーをdivに入れて以下のように修正します。



この時点で、タブのヘッダー部分が青い部分ではなくオレンジの部分に投影されているのがわかります。 その理由は、<ng-content select="header"></ng-content>が前のタグヘッダーと一致しないため、この部分のコンテンツが<ng-content></ng-content>オレンジの領域に投影されているからです。

この問題を解決するために、ngProjectAsプロパティを使わなければなりません。これは任意の要素に適用可能です。 詳細は以下の通りです。

ngProjectAsプロパティを設定することで、タグヘッダーがあるdivはselect="header"を指し、タグヘッダーの一部は青い領域に投影されます:



<ng-content>コンテンツを「生成」しないでください
実験をしてみて
実験を行うには、まずデモチャイルドコンポーネントを定義します:

デモコンポーネントから:

次に、demo-component cast demo-child-component では:


この時点でコンソールでは、demoの子コンポーネントの初期化が完了しているのが確認できます! この言葉。 しかし、操作を切り替えるボタンをクリックすると、demo-child-componentの初期化が完了します! もはや印刷されておらず、デモチャイルドコンポーネントは一度だけインスタンス化され、破棄されて再作成されることはありません。

なぜこんなことが起きているのでしょうか?

発生原因

コンテンツを<ng-content>「生成」するわけではなく、既存のコンテンツを投影しているだけです。 これはnode.appendChild(el)やjQueryの$(node).append(el)メソッドに相当すると考えられます。これらのメソッドではノードはクローン化されず、単に新しい場所に移動されます。 したがって、予測コンテンツのライフサイクルは宣言された場所に縛られ、その場で表示されるわけではありません。

これにより、原理からの前の質問も説明できます。もし複数のコンテンツが同時に存在した場合、外部コンテンツはどのように投影されるのでしょうか?

この挙動は二つの理由で行われます:一貫性とパフォーマンスです。 「望ましい一貫性」とは、開発者としてアプリケーションのコードからその挙動を推測できるという意味です。 例えば、私が次のコードを書いたとしましょう:

もちろん、demo-child-componentコンポーネントは一度インスタンス化されますが、サードパーティライブラリのコンポーネントを使うと:

サードパーティのライブラリがデモの子コンポーネントのライフサイクルを制御している場合、何回インスタンス化されたかを知る手段はありません。 これを実現する唯一の方法は、サードパーティライブラリのコードを見て内部処理ロジックを理解することです。 コンポーネントのライフサイクルをラッパーではなくアプリケーションコンポーネントに結びつける意味は、開発者がサードパーティライブラリの内部コードを知らずにカウンターを一度だけインスタンス化できるように管理できるということです。

性能の理由より重要だ。 ng-contentは単なる移動要素であるため、実行時ではなくコンパイル時に実行できるため、実際のアプリケーションの負荷を大幅に削減できます。

回避策

コンポーネントが投影されるサブコンポーネントのインスタンス化を制御するためには、2つの方法で可能です。すなわち、<ng-template>コンテンツの周りに要素やngTemplateOutletを使う方法、または「*」構文を持つ構造指令を使う方法です。 簡便さのため、例では構文を用います<ng-template>。

デモコンポーネントから:

次に ng-template に demo-child-component を含めます:

この時点でスイッチボタンを押すと、コンソールが出力されますdemo-child-componentの初期化完了!この言葉。





先の:Win10仮想マシン
次に:Git Extensions kdiff3のパスは自動的に認識されるわけではありません。
掲載地 2019/06/14 14:14:35 |
送って、変えて
免責事項:
Code Farmer Networkが発行するすべてのソフトウェア、プログラミング資料、記事は学習および研究目的のみを目的としています。 上記の内容は商業的または違法な目的で使用されてはならず、そうでなければ利用者はすべての結果を負うことになります。 このサイトの情報はインターネットからのものであり、著作権紛争はこのサイトとは関係ありません。 ダウンロード後24時間以内に上記の内容を完全にパソコンから削除してください。 もしこのプログラムを気に入ったら、正規のソフトウェアを支持し、登録を購入し、より良い本物のサービスを受けてください。 もし侵害があれば、メールでご連絡ください。

Mail To:help@itsvse.com