【问题标题】:Component template inheritance/composition组件模板继承/组合
【发布时间】:2020-02-24 09:33:23
【问题描述】:

应该如何在 Angular 组件之间共享重复的 UI 功能?

Angular 通过视图封装使这变得非常乏味。你不能在组件之间共享样式,除非你让它们成为全局的,破坏视图封装,这是一个不好的 Angular 实践。我能想到的唯一方法是通过内容投影,但这会导致组件结构非常扁平,并且您仍然无法共享 SCSS。

举个例子:

我有两种类型的“卡片”。第一个是唯一的,第二个可能会重复。

form-card.component.html

<mat-card class="crm-form-card" matRipple>
  <div class="crm-form-card-container">
    <mat-card-content class="crm-form-card-content">
      <mat-icon>{{ icon }}</mat-icon>
    </mat-card-content>
  </div>
</mat-card>

form-card.component.scss

@import 'abstracts/variables';

:host {
  height: 100%;
}

.crm-form-card,
.crm-form-card-container {
  height: 100%;
}

.crm-form-card {
  padding: 0;
  box-shadow: none !important;
  cursor: pointer;
}

.crm-form-card-container {
  display: flex;
  flex-wrap: nowrap;
  justify-content: center;
  align-content: center;
}

.crm-form-card,
.crm-form-card-content {
  margin: 0;
}

form-card-edit.component.html

<mat-card class="crm-form-card" matRipple>
  <div class="crm-form-card-container">
    <mat-card-title
      class="crm-form-card-title"
      crmDisableEventPropagation="mousedown"
    >
      Form 1
    </mat-card-title>
    <div class="crm-form-card-options">
      <mat-menu #appMenu="matMenu">
        <button mat-menu-item>Filter 1</button>
        <mat-divider></mat-divider>
        <button mat-menu-item>Filter 2</button>
      </mat-menu>

      <button
        [matMenuTriggerFor]="appMenu"
        mat-icon-button
        crmDisableEventPropagation="mousedown"
      >
        <mat-icon>more_horiz</mat-icon>
      </button>
    </div>
    <mat-card-content class="crm-form-card-content">
      <mat-icon>edit</mat-icon>
    </mat-card-content>
    <mat-card-actions
      class="crm-form-card-actions"
      crmDisableEventPropagation="mousedown"
    >
      Created 03/06/19
    </mat-card-actions>
  </div>
</mat-card>

form-card-edit.component.scss

@import 'abstracts/variables';

:host {
  height: 100%;
}

.crm-form-card,
.crm-form-card-container {
  height: 100%;
}

.crm-form-card {
  padding: 0;
  box-shadow: none !important;
  cursor: pointer;
}

.crm-form-card-container {
  display: grid;
  grid-template-columns: auto auto;
  grid-template-rows: auto 1fr auto;
  grid-template-areas:
    'title options'
    'edit .'
    'actions .';
}

.crm-form-card-title,
.crm-form-card-actions {
  padding: $charm-spacing-small;
}

.crm-form-card-title {
  grid-area: title;
  font-size: 16px;
  color: #333;
  justify-self: start;


align-self: start;
}

.crm-form-card-options {
  grid-area: options;
  justify-self: end;
  align-self: start;
  padding: 4px;
}

.crm-form-card-content {
  grid-area: edit / span 2;
  justify-self: center;
  align-self: center;
}

.crm-form-card-actions {
  grid-area: actions / span 2;
  justify-self: start;
  align-self: end;
}

.mat-card,
.crm-form-card-title,
.crm-form-card-content,
.crm-form-card-actions {
  margin: 0;
}

它们共享大量的 SASS 和 HTML。

【问题讨论】:

  • 可能我对你的问题不是很清楚,但你为什么不为两个(每个)共享组件创建通用 SCSS/CSS 文件并注入所有共享组件,因为你可以添加styleUrls中的多个 CSS 文件

标签: angular


【解决方案1】:

我最终使用内容投影以及select 和已弃用的:host ::ng-deep 来解决我的问题。

form-card.component.html

<mat-card class="crm-form-card" matRipple>
  <div class="crm-form-card-container">
    <ng-content select=".crm-form-card-title"></ng-content>
    <ng-content select=".crm-form-card-options"></ng-content>
    <ng-content select=".crm-form-card-content"></ng-content>
    <ng-content select=".crm-form-card-actions"></ng-content>
  </div>
</mat-card>

form-card-add.component.html

<crm-form-card>
  <mat-card-content class="crm-form-card-content">
    <mat-icon>add</mat-icon>
  </mat-card-content>
</crm-form-card>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-02
    • 2011-05-20
    相关资源
    最近更新 更多