[Angular] Content Projection with ng-content
For example there is tow form compoennts on the page, and what we want to do is reusing the form component. Make to tow form behave differently, we can using <ng-content> inside form and pass what we want from the parent component.
// app.component.ts <div> <auth-form (submitted)="createUser($event)"> <h3>Create account</h3> <button type="submit"> Join us </button> </auth-form> <auth-form (submitted)="loginUser($event)"> <h3>Login</h3> <button type="submit"> Login </button> </auth-form> </div>
For each form we have different event handler such as 'createUser' and 'loginUser'. Besides that for each form we pass one h3 tag and one button tag.
To see how it should looks like:
Now let's see how to write form component to make this happen.
// auth-form.component.ts <div> <form (ngSubmit)="onSubmit(form.value)" #form="ngForm"> <ng-content select="h3"></ng-content> <label> Email address <input type="email" name="email" ngModel> </label> <label> Password <input type="password" name="password" ngModel> </label> <ng-content select="button"></ng-content> </form> </div>
<ng-content> has 'select' attr, which is similar to css selector, you can use component, class, id...
The way I prefer is attribute selector:
<auth-form (submitted)="createUser($event)"> <h3 auth-form-title>Create account</h3> <button auth-form-submit type="submit"> Join us </button> </auth-form>
So we you can use it like:
<div> <form (ngSubmit)="onSubmit(form.value)" #form="ngForm"> <ng-content select="[auth-form-title]"></ng-content> <label> Email address <input type="email" name="email" ngModel> </label> <label> Password <input type="password" name="password" ngModel> </label> <ng-content select="[auth-form-submit]"></ng-content> </form> </div>
ng-content also accept customer component.
For example, there is a component:
@Component({ selector: 'auth-remember', template: ` <label> <input type="checkbox" (change)="onChecked($event.target.checked)"> Keep me logged in </label> ` }) export class AuthRememberComponent { @Output() checked: EventEmitter<boolean> = new EventEmitter<boolean>(); onChecked(value: boolean) { this.checked.emit(value); } }
And we can use it:
<auth-form (submitted)="loginUser($event)"> <h3>Login</h3> <auth-remember (checked)="rememberUser($event)"> </auth-remember> <button type="submit"> Login </button> </auth-form>
Insie form component, we add slot for the new component.
<div> <form (ngSubmit)="onSubmit(form.value)" #form="ngForm"> <ng-content select="h3"></ng-content> <label> Email address <input type="email" name="email" ngModel> </label> <label> Password <input type="password" name="password" ngModel> </label> <ng-content select="auth-remember"></ng-content> <ng-content select="button"></ng-content> </form> </div>
Lastly, just like 'switch' in any programming lanugage, it has a 'default' case, for content projection is the same, anything which is not match to the selector, it will goes to default slot. So how to define a default slot for content projection?
Actually it is quite símple:
<div> <ng-content select=".higlight"></ng-content> <ng-content select="authComponent"></ng-content> <!-- Default case--> <ng-content></ng-content> </div>
相关文章
- 关于 Angular 里 module 和 Component 包含粒度的一个讨论
- angular面试问题_kafka面试题
- 如何在Angular项目中使用MQTT
- 关于 SAP Spartacus Angular HTTP Interceptor 的拦截顺序
- Angular HTTPClient API 在 SAP 电商云中的使用
- Angular HTTPClient 发送请求的触发方式讨论
- Angular 14 新的 inject 函数介绍
- 关于 Angular Universal 应用执行时需要 Browser API 的问题
- Angular 应用里 server.ts 文件的 APP_BASE_HREF token 的用法?
- Angular 服务器端渲染场景里,服务器端和客户端渲染出的 HTML 源代码有可能不完全一致
- 关于 Angular 12 的 inlineCriticalCss 选项
- ORA-39322: Cannot use transportable tablespace with TIMESTAMP WITH TIME ZONE columns and different time zone version. ORACLE 报错 故障修复 远程处理
- Angular和jQuery的区别
- Oracle 中的 WITH 语句使用技巧(oracle with用法)
- 语句Oracle中简洁的With语句(oracle 中with)
- 分析学习Oracle深入理解使用With 分析(oracle使用with)
- 从Oracle中挖掘洞见坚实的With表(oracle with表)
- 基于豆瓣API+Angular开发的webApp