[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>

 

posted @   Zhentiw  阅读(398)  评论(0编辑  收藏  举报
编辑推荐:
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
历史上的今天:
2016-02-19 [Immutable + AngularJS] Use Immutable .List() for Angular array
2016-02-19 [Protractor] Running tests on multiple browsers
2016-02-19 [Protractor] Protractor Interactive with elementor
点击右上角即可分享
微信分享提示