Angular でのコンテンツ投影の方法について話しましょう

青灯夜游
リリース: 2022-05-12 10:41:28
オリジナル
2194 人が閲覧しました

この記事では、angular でのコンテンツ投影について説明し、コンテンツ投影に ng-content を使用する方法を紹介し、条件付きコンテンツ投影の実装方法を理解します。 !

Angular でのコンテンツ投影の方法について話しましょう

1. ng-content コンテンツ投影

1.1 <span style="font-size: 16px;">ng-content</span>

ng-content 要素は、外部または動的コンテンツ シンボルを挿入するために使用される プレースホルダーです## #。親コンポーネントは、外部コンテンツを子コンポーネントに渡します。Angularがテンプレートを解析すると、外部コンテンツは子コンポーネントのテンプレートに挿入されます。と表示されます。 [関連チュートリアルの推奨事項: "angular チュートリアル"] コンテンツ プロジェクションを使用して、再利用可能なコンポーネントを作成できます。これらのコンポーネントは同様のロジックとレイアウトを備えており、多くの場所で使用できます。一般に、いくつかのパブリック コンポーネントを カプセル化する場合によく使用されます。

1.2 コンテンツ プロジェクションを使用する理由

ボタン コンポーネントを定義します:

button-component.ts

@Component({
    selector: &#39;[appButton]&#39;,
    template: `
    <span class="icon-search"></span>
`
})
export class AppButtonComponent {}
ログイン後にコピー

このボタン コンポーネントの目的は、ボタン内に検索アイコンを追加することです。実際には次のように使用します: <div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:js;toolbar:false;">&lt;button appButton&gt;click&lt;/button&gt;</pre><div class="contentsignin">ログイン後にコピー</div></div><div class="contentsignin">ログイン後にコピー</div></div>コンポーネントは検索アイコンのみを表示することがわかりました。ボタンのテキストは表示されません。最も一般的に使用される

@Input

デコレータを思い浮かべるかもしれませんが、テキストだけでなく ## の段落を渡したい場合はどうなるでしょうか。 #html

?現時点では

ng-content が使用されます。 1.3 シングル スロット コンテンツ プロジェクション

コンテンツ プロジェクションの最も基本的な形式は、シングル スロット コンテンツ プロジェクションです。

単一スロット コンテンツの投影とは、コンポーネントを投影できるコンポーネントを作成することを指します。

ボタン コンポーネントを例として、単一スロット コンテンツ プロジェクションを作成します。

button-component.ts

@Component({
    selector: &#39;[appButton]&#39;,
    template: `
    <span class="icon-search"></span> <ng-content></ng-content>
`
})
export class AppButtonComponent {}
ログイン後にコピー

実際の使用法は次のとおりです。

<div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:js;toolbar:false;">&lt;button appButton&gt;click&lt;/button&gt;</pre><div class="contentsignin">ログイン後にコピー</div></div><div class="contentsignin">ログイン後にコピー</div></div> このボタン コンポーネントの効果は、検索アイコンとボタン (クリック) のテキストの両方を表示することであることがわかります。つまり、

の中央にあるコンテンツ

は、

ng-content 要素はプレースホルダーであり、実際の DOM 要素を作成するものではありません。 ng-content のカスタム属性は無視されます。

1.4 マルチスロット コンテンツ プロジェクション

コンポーネントは

複数のスロット を持つことができ、各 A スロットはCSS セレクター を指定します。これにより、スロットに入るコンテンツが決定されます。このモードは、マルチスロット コンテンツ プロジェクション

と呼ばれます。このモードを使用すると、投影されたコンテンツ

を表示する位置 を指定する必要があります。これは、ng-contentselect 属性を使用して実行できます。 コンポーネント テンプレートには、 複数の

ng-content
タグが含まれています。
    対応する
  • ng-content タグ に投影できる投影されたコンテンツを区別するには、ng の select 属性を使用する必要があります。 -content
  • タグを識別として使用します。
  • select 属性は、tag nameproperty
  • CSS class :not pseudo-class# をサポートします。 # # の任意の組み合わせ。 select 属性を追加しない ng-content タグは、default スロットとして機能します。一致しない投影されたコンテンツはすべて、この ng-content の場所に投影されます。
  • ボタン コンポーネントを例として、マルチスロット コンテンツ プロジェクションを作成します: button-component.ts
    @Component({
        selector: &#39;[appButton]&#39;,
        template: `
        <span class="icon-search"></span> <ng-content select="[shuxing]"></ng-content> <ng-content select="p"></ng-content> <ng-content select=".lei"></ng-content>
    `
    })
    export class AppButtonComponent {}
    ログイン後にコピー
    実際の使用法は次のとおりです。
    <button appButton>
    <p>click</p> <span shuxing>me</span> <span class="lei">here</span>
    </button>
    ログイン後にコピー

1.5

ngProjectAs

場合によっては、 ng-container を使用する必要があります。コンテンツをラップしてコンポーネントに渡します。ほとんどの場合、ngIf や <span style="font-size: 16px;">ngSwitch</span> などの構造ディレクティブを使用する必要があることが原因です。 。 以下の例では、

header

ng-container でラップしています。 <div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:js;toolbar:false;">@Component({ selector: &amp;#39;app-card&amp;#39;, template: ` &lt;div class=&quot;card&quot;&gt; &lt;div class=&quot;header&quot;&gt; &lt;ng-content select=&quot;header&quot;&gt;&lt;/ng-content&gt; &lt;/div&gt; &lt;div class=&quot;content&quot;&gt; &lt;ng-content select=&quot;content&quot;&gt;&lt;/ng-content&gt; &lt;/div&gt; &lt;div class=&quot;footer&quot;&gt; &lt;ng-content select=&quot;footer&quot;&gt;&lt;/ng-content&gt; &lt;/div&gt; &lt;ng-content&gt;&lt;/ng-content&gt; &lt;/div&gt; ` }) export class AppCardComponent {}</pre><div class="contentsignin">ログイン後にコピー</div></div>使用法: <div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:js;toolbar:false;">&lt;app-card&gt; &lt;ng-container&gt; &lt;header&gt; &lt;h1&gt;Angular&lt;/h1&gt; &lt;/header&gt; &lt;/ng-container&gt; &lt;content&gt;One framework. Mobile &amp; desktop.&lt;/content&gt; &lt;footer&gt;&lt;b&gt;Super-powered by Google &lt;/b&gt;&lt;/footer&gt; &lt;/app-card&gt;</pre><div class="contentsignin">ログイン後にコピー</div></div>

ng-container

が存在するため、header 部分はレンダリングしたいスロットにレンダリングされません. の代わりに、selector を提供しない

ng-content

にレンダリングされます。

この場合、

ngProjectAs 属性を使用できます。 この属性を上記の ng-container に追加すると、期待どおりにレンダリングできます。 <div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:js;toolbar:false;">&lt;app-card&gt; &lt;ng-container ngProjectAs=&amp;#39;header&amp;#39;&gt; &lt;header&gt; &lt;h1&gt;Angular&lt;/h1&gt; &lt;/header&gt; &lt;/ng-container&gt; &lt;content&gt;One framework. Mobile &amp; desktop.&lt;/content&gt; &lt;footer&gt;&lt;b&gt;Super-powered by Google &lt;/b&gt;&lt;/footer&gt; &lt;/app-card&gt;</pre><div class="contentsignin">ログイン後にコピー</div></div><h2><strong>二、 有条件的内容投影</strong></h2><p>如果你的元件需要有条件地渲染内容或多次渲染内容,则应配置该元件以接受一个 <code>ng-template 元素,其中包含要有条件渲染的内容。

在这种情况下,不建议使用 ng-content 元素,因为只要元件的使用者提供了内容,即使该元件从未定义 ng-content 元素或该 ng-content 元素位于 ngIf 语句的内部,该内容也总会被初始化。

使用 ng-template 元素,你可以让元件根据你想要的任何条件显式渲染内容,并可以进行多次渲染。在显式渲染 ng-template 元素之前,Angular 不会初始化该元素的内容。

2.1 <span style="font-size: 16px;">ng-container</span>

既不是一个组件,也不是一个指令,仅仅是一个特殊的tag而已。 使用 ng-container 渲染所包含的模板内容,不包含自身。

  • angular代码片段
<div>
  <ng-container>
    <p>My name is wyl.</p>
    <p>What is you name?</p>
  </ng-container>
</div>
ログイン後にコピー
  • 浏览器调试窗口,可以发现 <ng-container> 标签消失了,并没有起任何作用
<div>
  <p>My name is wyl.</p>
  <p>What is you name?</p>
</div>
ログイン後にコピー
  • 使用场景,如下,在我们需要遍历if 判断 时,它可以承担一个载体的作用
<ul>
  <ng-container *ngFor="let item of items">
    <li>{{ item .name}}</li>
    <li>{{ item .age}}</li>
    <li>{{ item .sex}}</li>
  </ng-container>
</ul>
ログイン後にコピー

另外,ng 中常见错误之一的 forif 不能写在同一标签上(在一个宿主元素上只能应用一个结构型指令),利用 ng-container 标签可以在实现功能的基础上减少层级的嵌套。

2.2 <span style="font-size: 16px;">ng-template</span>

先来看下面一段代码

<ng-template>
    <p> In template, no attributes. </p>
</ng-template>

<ng-container>
    <p> In ng-container, no attributes. </p>
</ng-container>
ログイン後にコピー

浏览器输出结果是:

In ng-container, no attributes.
ログイン後にコピー

<ng-template> 中的内容不会显示。当在上面的模板中添加 ngIf 指令:

<ng-template [ngIf]="true">
   <p> ngIf with a ng-template.</p>
</ng-template>

<ng-container *ngIf="true">
   <p> ngIf with an ng-container.</p>
</ng-container>
ログイン後にコピー

浏览器输出结果是:

ngIf with a ng-template.
ngIf with an ng-container.
ログイン後にコピー

2.3 <span style="font-size: 16px;">ng-template</span><ng-container> 的配合使用

<ng-container *ngIf="showSearchBread; else tplSearchEmpty">
     暂时搜索不到您要的数据喔
</ng-container>
<ng-template #tplSearchEmpty>
     快快开始获取吧!
</ng-template>
ログイン後にコピー

2.4 <span style="font-size: 16px;">ngTemplateOutlet</span>

插入 ng-template 创建的内嵌视图。 ngTemplateOutlet 是一个结构型指令,接收一个 TemplateRef 类型的值;

<div *ngTemplateOutlet="tpl1"></div>
<ng-template #tpl1>
  <span>I am span in template {{title}}</span>
</ng-template>
ログイン後にコピー

*ngTemplateOutlet = "templateRefExp; content: contentExp "

  • templateRefExp: ng-template 元素的 #ID
  • contextExp:
    • 可空参数

    • content 是一个对象,这个对象可以包含一个 $implicitkey 作为默认值, 使用时在 模板 中用 let-key 语句进行绑定

    • content 的非默认字段需要使用 let-templateKey=contentKey 语句进行绑定

使用如下:

@Component({
  selector: &#39;ng-template-outlet-example&#39;,
  template: `
    <ng-container *ngTemplateOutlet="greet"></ng-container>
    <hr>
    <ng-container *ngTemplateOutlet="eng; context: myContext"></ng-container>
    <hr>
    <ng-container *ngTemplateOutlet="svk; context: myContext"></ng-container>
    <hr>
    <ng-template #greet><span>Hello</span></ng-template>
    <ng-template #eng let-name><span>Hello {{name}}!</span></ng-template>
    <ng-template #svk let-person="localSk"><span>Ahoj {{person}}!</span></ng-template>
`
})
class NgTemplateOutletExample {
  myContext = {$implicit: &#39;World&#39;, localSk: &#39;Svet&#39;};
}
ログイン後にコピー

2.5 利用 <span style="font-size: 16px;">ngTemplateOutlet</span> 进行内容投影

@Component({
    selector: &#39;app-card&#39;,
    template: `
		<div class="card">
		  <div class="header">
		  	<ng-container *ngTemplateOutlet="headerTemplate; context: { $implicit: title, index: otherDate }"></ng-container>
		  </div>
		</div>
`
})
export class AppCardComponent {

	@ContentChild(&#39;header&#39;, { static: true }) headerTemplate: TemplateRef<any>;

	public title = &#39;Test&#39;;
	public otherDate = {
	 	auth: &#39;me&#39;,
	 	name: &#39;appCard&#39;
	};
}
ログイン後にコピー

使用

<app-card>
  <ng-template #header let-label let-item="otherDate">
    <h1>Angular</h1> {{label}} (Test) and  {{otherDate | json}} ({auth: &#39;me&#39;, name: &#39;appCard&#39;})
  </ng-template>
</app-card>
ログイン後にコピー

更多编程相关知识,请访问:编程教学!!

以上がAngular でのコンテンツ投影の方法について話しましょうの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:csdn.net
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート