如何创建具有相同逻辑的多个组件或具有多个模板的1个组件?

时间:2019-11-03 18:57:52

标签: angular angular8

我在允许多列排序的报表中为表样式数据构建了标题行组件。这非常简单:一个属性,两个函数和一个@Output()可以在顺序更改时让父组件知道。

我现在想在我拥有的所有其他报告中使用该组件-每个报告都有相同的逻辑,但是它们每个都有不同的显示。

我知道我可以为报表类型添加@Input(),然后在模板中添加* ngSwitch代码,但是我很想找到一种方法将每个标头的HTML实际隔离到它自己的文件中(可能是也拥有自己的SCSS文件),而无需创建一堆具有完全相同逻辑的组件。

下面的逻辑只是为了好玩。

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

@Component({
  selector: 'sort-row',
  templateUrl: './sort-row.component.html',
  styleUrls: ['./sort-row.component.scss']
})
export class SortRowComponent {

  sortOrder: string[] = [];

  @Output() sortChanged: EventEmitter<string[]> = new EventEmitter<string[]>();

  constructor() {}

  sortingBy(field, dir?) {
    if (dir) {
      if (dir === 'desc') {
        field = '-' + field;
      }
      return this.sortOrder.indexOf(field) !== -1;
    } else {
      return this.sortOrder.indexOf(field) !== -1 || this.sortOrder.indexOf('-' + field) !== -1;
    }

  }

  toggleSortCol(col, evt) {

    const ascIdx = this.sortOrder.indexOf(col);
    const descIdx = this.sortOrder.indexOf('-' + col);

    if (!evt.shiftKey) {

      if (ascIdx !== -1) {
        this.sortOrder = ['-' + col];
      } else if (descIdx !== -1) {
        this.sortOrder = [col.replace('-', '')];
      } else {
        this.sortOrder = [col];
      }

    } else {

      if (ascIdx !== -1) {
        this.sortOrder[ascIdx] = '-' + col;
      } else if (descIdx !== -1) {
        this.sortOrder[descIdx] = col.replace('-', '');
      } else {
        this.sortOrder.push(col);
      }
    }

    this.sortChanged.next(this.sortOrder);
  }
}

2 个答案:

答案 0 :(得分:1)

因此,当您希望使用相同逻辑的多个组件同时具有不同的标记时,您只需要简单地创建另一个组件即可。用逻辑扩展一个。并使用OOP的所有优点(继承的道具和方法)。

答案 1 :(得分:0)

我认为您可以向通用组件中添加新的@Input() customCSSClasses: Object并从主机组件传递新的CSS类,并在所选元素上使用ngClass来应用这些自定义类(您需要添加这些自定义类全局styles.css文件中的类。)

例如:

// Host component.html
<sort-row [customCSSClasses]="{input: 'dark-input', select: 'dark-lg-select'}" 
          // the other config
></sort-row>


// sort-row component.ts
@Input() customCSSClasses?: Object;

// sort-row component.html
<input [ngClass]="customCSSClasses?.input ? customCSSClasses?.input : 'default-input'">
<select [ngClass]="customCSSClasses?.select ? customCSSClasses?.select : 'default-select'"></select