0

Hello angular community,

I want to ask about a good way to make an icon-component generic and avoid code duplication

delete-icon-component:

@Component({
  selector: 'app-delete-row-icon',
  template: `
    <style>
      button {
        background-color: Transparent;
        border: none;
        cursor: pointer;
        overflow: hidden;
        outline: none;
      }

      mat-icon {
        font-size: 18px;
      }
    </style>
    <button (click)="onClickDeleteIcon($event)">
      <mat-icon
        matTooltip="Unselect file"
        matTooltipPosition="below"
        class="material-icons-outlined"
        >{{ iconRegistry.REMOVE }}</mat-icon
      >
    </button>
  `,
  styles: [],
  changeDetection: ChangeDetectionStrategy.OnPush
})
export class DeleteRowIconComponent implements ICellRendererAngularComp {
  params;
  disabled = false;
  iconRegistry = IconRegistry;

  agInit(params): void {
    this.refresh(params);
  }

  refresh(params): boolean {
    this.params = params;
    return true;
  }

  onClickDeleteIcon($event): void {
    const params = {
      rowData: this.params.data,
      rowIndex: this.params.rowIndex
    };
    this.params.onClick(params);
  }

remove-icon-component:

import { ChangeDetectionStrategy, Component } from '@angular/core';
import { ICellRendererAngularComp } from 'ag-grid-angular';
import { IconRegistry } from '../../../icon-registry/icon-registry';

@Component({
  selector: 'app-remove-icon-render',
  template: `
    <style>
      button {
        background-color: Transparent;
        border: none;
        cursor: pointer;
        overflow: hidden;
        outline: none;
      }
      button :hover {
        background-color: #efeadf;
      }
      mat-icon {
        font-size: 18px;
      }
    </style>
    <button
      *ngIf="params?.data && !!params.data.objectId && !!params.data.objectPath"
      (click)="onClick($event)"
      [disabled]="params?.disabledGetter ? params.disabledGetter(params) : false"
      data-cy="icon-cell-Delete"
    >
      <mat-icon [matTooltip]="tooltip" matTooltipPosition="below" class="material-icons-outlined">
        {{ iconRegistry.MINUS }}
      </mat-icon>
    </button>
  `,
  styles: [],
  changeDetection: ChangeDetectionStrategy.OnPush
})

export class RemoveIconRenderComponent implements ICellRendererAngularComp {
  params;
  iconRegistry = IconRegistry;
  tooltip: string;

  agInit(params): void {
    this.params = params;
    if (this.params?.tooltipGetter) {
      this.tooltip = this.params.tooltipGetter(this.params);
    } else {
      this.tooltip = this.params?.tooltip;
    }
  }

  onClick($event): void {
    $event.stopPropagation();
    const params = {
      rowData: this.params.node.data
    };
    this.params.onClick(params);
  }

  refresh(params): boolean {
    this.params = params;
    return true;
  }

the only difference is the ICON and the logic behind agInit function

I cannot use the @Input feature, because I will use these components inside ts code and not HTML code this way:

  this.frameworkComponents = {
      deleteButtonRenderer: DeleteIconRenderComponent
    };

So any good recommended way to make one generic component that can accept any icon ?

1 Answer 1

1

You could create an abstract RowIconComponent and extend from it. Something like this:

export abstract class IconComponent {
  params;
  iconRegistry = IconRegistry;
  tooltip: string;

  refresh(params): boolean {
    this.params = params;
    return true;
  }

  abstract onClick($event): void;
  abstract agInit(params): void;
}

And changed example:

@Component({
  // ...
})
export class DeleteRowIconComponent extends IconComponent implements ICellRendererAngularComp {
  agInit(params): void {
    this.refresh(params);
  }

  onClick($event): void {
    const params = {
      rowData: this.params.data,
      rowIndex: this.params.rowIndex
    };
    this.params.onClick(params);
  }
}
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks, it looks good what we should do for the HTML code? we can add it the abstract class?
Not sure about that, try it out

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.