You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular:如何复用GridComponent并根据场景加载不同子组件

解决方案:用内容投影实现可复用的Grid卡片容器

1. 重构GridComponent模板,改为内容投影容器

把原来硬编码的title1-4和content1-4替换为<ng-content>,通过select属性指定每个卡片的位置,让父组件可以灵活传入任意子组件:

<div class="container col-md-6">
  <div class="row">
    <div class="card-group">
      <div class="card h-100">
        <!-- 第一个卡片的内容投影槽 -->
        <ng-content select="[card-position='1']"></ng-content>
      </div>
      <div class="card h-100">
        <!-- 第二个卡片的内容投影槽 -->
        <ng-content select="[card-position='2']"></ng-content>
      </div>
    </div>
  </div>

  <div class="row">
    <div class="card-group">
      <div class="card h-100">
        <!-- 第三个卡片的内容投影槽 -->
        <ng-content select="[card-position='3']"></ng-content>
      </div>
      <div class="card h-100">
        <!-- 第四个卡片的内容投影槽 -->
        <ng-content select="[card-position='4']"></ng-content>
      </div>
    </div>
  </div>
</div>

2. 创建独立的卡片子组件

为每类数据(天气、新闻、推特等)单独创建组件,每个组件负责自己的标题和内容渲染。比如创建WeatherCardComponent:

组件模板(weather-card.component.html):

<div class="card-body">
  <h5 class="card-title">天气</h5>
  <!-- 这里写天气相关的内容逻辑,比如绑定组件内的数据 -->
  <p class="card-text">今日气温:{{ temperature }}°C</p>
</div>

组件类(weather-card.component.ts):

import { Component } from '@angular/core';

@Component({
  selector: 'app-weather-card',
  templateUrl: './weather-card.component.html'
})
export class WeatherCardComponent {
  // 可通过服务或输入属性获取数据
  temperature = 25;
}

同理,创建NewsCardComponent、TwitterCardComponent、SettingsCard5Component、SettingsCard6Component等,每个组件对应一类数据的展示逻辑。

3. 在父组件中使用GridComponent,传入对应卡片

在首页(HomeComponent)的模板中,将需要的4个卡片组件放到app-grid标签内,通过card-position属性指定位置:

<app-grid>
  <app-weather-card card-position="1"></app-weather-card>
  <app-news-card card-position="2"></app-news-card>
  <app-twitter-card card-position="3"></app-twitter-card>
  <app-sports-card card-position="4"></app-sports-card>
</app-grid>

在设置页(SettingsComponent)的模板中,传入另一组卡片:

<app-grid>
  <app-settings-card5 card-position="1"></app-settings-card5>
  <app-settings-card6 card-position="2"></app-settings-card6>
  <app-twitter-card card-position="3"></app-twitter-card>
  <app-sports-card card-position="4"></app-sports-card>
</app-grid>

为什么构造函数传递组件无效?

Angular的构造函数是用来注入依赖(比如服务、路由等)的,不是用来传递子组件或视图内容的。组件间传递视图内容的标准方式是内容投影,传递数据则用@Input输入属性,这是Angular组件交互的核心机制。

可选优化:用输入属性传递卡片配置(适合卡片结构高度一致的场景)

如果所有卡片结构完全相同,仅标题和数据不同,可以不用创建多个子组件,而是给GridComponent传入卡片配置数组:

GridComponent类:

import { Component, Input } from '@angular/core';

interface CardConfig {
  title: string;
  content: string | any; // 支持字符串或复杂数据结构
}

@Component({
  selector: 'app-grid',
  templateUrl: './grid.component.html'
})
export class GridComponent {
  @Input() cards: CardConfig[] = [];
}

GridComponent模板:

<div class="container col-md-6">
  <div class="row">
    <div class="card-group">
      <div class="card h-100" *ngFor="let card of cards.slice(0,2)">
        <div class="card-body">
          <h5 class="card-title">{{ card.title }}</h5>
          {{ card.content }}
        </div>
      </div>
    </div>
  </div>

  <div class="row">
    <div class="card-group">
      <div class="card h-100" *ngFor="let card of cards.slice(2,4)">
        <div class="card-body">
          <h5 class="card-title">{{ card.title }}</h5>
          {{ card.content }}
        </div>
      </div>
    </div>
  </div>
</div>

首页父组件中传入配置:

<app-grid [cards]="[
  { title: '天气', content: '今日气温25°C' },
  { title: '新闻', content: '最新科技资讯' },
  { title: '推特', content: '热门推文' },
  { title: '体育', content: '赛事播报' }
]"></app-grid>

这种方式更适合卡片结构统一的场景,内容投影则更适合每个卡片有独立交互逻辑的情况。

内容的提问来源于stack exchange,提问作者Vejdis

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 05:01:08