畫面需要重複利用的內容時,可利用嵌入內容設計 (transclusion) 來達成,是一個內容投射 (content projection) 的概念
Content projection with ng-content (投射全部內容)
如下圖所示,在 app-root
畫面,使用了兩個 auth-form
的元件內容,但auth-form
的 title 因為寫死了,所以現在畫面都長一樣,有沒有更好的做法呢? 可以使用 ng-content !
使用 ng-content
所以在兩個 auth-form
內寫了<h3>
的內容,然後auth-form
加上 ng-content
如此 ng-content
就會把我們定義的 <h3>
內容投射進去 (因為在左邊我們也沒有定義其他內容)
成功的置換了 title,大功告成
Using ng-content with projection slots (用 select 指定投射內容)
現在我們希望把下面的按鈕也換掉,所以多加了一個按鈕
但會發現按鈕都在上面,因為現在只有使用<ng-content>
,所以他會把 “所有” 內容都投射進去
所以如果想要把 title 的位置放上面,按鈕在下面的位置
可以使用 ng-content + select
這個例子
ng-content + select (HTML tag or css selector 語法)
1 | <ng-content select="像是使用 css selector"></ng-content> |
1 | //用 class 去找 |
1 | //用 attibute 去找 |
1 | //用 HTML TAG 去找 |
Projecting and binding to components (投射 componet)
同樣的概念下,我們也可以把自己做的 component directive
利用 content projection
投射到某個畫面上
這個例子中,我們想要加上一個 remember me 的 component 到畫面上,如下圖
這裡定義一個 auth-remember
的 component directive, 然後使用 ng-content 投射內容
1 | <ng-content select="auth-remember"></ng-content> |
auth-remember.componet.ts
remember me componet: 提供一個 checkbox 勾選後,會送出是否記得帳號(true or false)
1 | import { Component, Output, EventEmitter } from '@angular/core'; |
auth-form.componet.ts
在第 20 行, 加上了新的 remember me 的 auth-remember component
在 28 行透過 @Output() submitted() 給 父 component: app.componet.ts
讓 app.componet.ts 再去呼叫不同的方法 createUser() or loginUser()
1 | import { Component, Output, EventEmitter } from '@angular/core'; |
app.componet.ts
1 | import { Component } from '@angular/core'; |
第一個
第二個
這裡的 btn 都有宣告 type="submit"
所以按下 btn 時, 都會啟動 auth-form component 裡的 form submit
1 | <form (ngSubmit)="onSubmit(form.value)" #form="ngForm"> |
這個 form submit 會呼叫 auth-form Component 的 "onSubmit(form.value)"
方法
1 | onSubmit(value: User) { |
"onSubmit(form.value)"
這方法會呼叫 AuthForm Component 定義的 @Output() submitted 事件,
1 | @Output() submitted: EventEmitter<User> = new EventEmitter<User>(); |
this.submitted.emit(value)
emit 事件出去後,會呼叫 app componet (submitted) 事件綁定的方法
所以…
第一個
1 | (submitted)="loginUser($event)" |
第二個
1 | (submitted)="rememberUser($event)" |
Result
感想
ng-content 是個蠻方便的東西,但最後一個例子其實寫起來好像有點複雜XD…是不是開新帳號和登入頁分開寫還比較簡單哈…