在运行时使用指令动态替换新的 PrimeNG 复选框图标

问题描述 投票:0回答:1

我正在寻找一种解决方法来替换新的复选框检查图标,因为 Angular + primeng 更新了已更改的图标,但我想使用它的旧版本。

请在此处找到我的问题的最小复制品。

我的想法是用指令定位所有

<p-checkbox>
并以某种方式替换
<checkicon>

我尝试在指令构造函数中使用

viewContainerRef
,但随后 viewContainerRef 定位了错误的 html 元素(p-checkbox),并且图标插入到了错误的位置。

@Directive({
  selector: 'p-checkbox',
})
export class IconDirective {
  constructor(private viewContainerRef: ViewContainerRef) {}
}

然后我尝试直接定位 PrimeNG 的

checkicon
元素,因为这是我想用自定义图标替换检查图标的地方,但这似乎不起作用。

@Directive({
  selector: 'checkicon',
})
export class IconDirective {
  constructor(private viewContainerRef: ViewContainerRef) {}

@HostListener('click', ['$event']) onModelChange(): void {
  setTimeout(() => {
    this.replaceCheckIcon();
  });
}

  async replaceCheckIcon() {
    this.viewContainerRef.clear();
    this.viewContainerRef.createComponent(CustomIcon);
  }
}

以下选项对我不起作用:

  1. 新引入的

    checkboxIcon
    属性,因为我使用了
    pi pi-times
    图标,但是这个图标的外观发生了变化。

  2. 直接触摸/更改任何html,因为在我的项目中有数千个复选框,我不会将带有自定义图标的

    <ng-template pTemplate="icon">
    添加到所有复选框出现中。

  3. <ng-container #target>
    添加到我的任何 html 中以从
    ViewChild
    查询中获取 viewContainerRef 也不是一个选项,但以编程方式添加它是一个选项,但我无法弄清楚。

javascript angular typescript primeng primeicons
1个回答
0
投票

首先你需要检查我使用的旧图标是否存在

querySelector
,然后我使用
renderer2
removeChild
方法删除它。

然后我们可以使用

createComponent
API来创建组件。然后使用
addClass
为图标添加默认的 primeng 类,最后使用
appendChild
在旧图标所在的位置插入新图标。

希望您使用此代码并满足您的要求。

import {
  Directive,
  ElementRef,
  HostListener,
  Renderer2,
  ViewContainerRef,
  createComponent,
  Injector,
  EnvironmentInjector,
  ChangeDetectorRef,
} from '@angular/core';
import { CustomIcon } from './icon/custom-icon';

@Directive({
  selector: 'p-checkbox',
})
export class IconDirective {
  @HostListener('click', ['$event']) onModelChange(): void {
    setTimeout(() => {
      this.replaceCheckIcon();
    });
  }

  constructor(
    private elementRef: ElementRef,
    private viewContainerRef: ViewContainerRef,
    private renderer: Renderer2,
    private environmentInjector: EnvironmentInjector,
    private cdr: ChangeDetectorRef
  ) {}

  replaceCheckIcon() {
    const oldIcon = this.elementRef.nativeElement.querySelector('checkicon');
    const newIcon = this.elementRef.nativeElement.querySelector('custom-icon');
    const checkboxContainer =
      this.elementRef.nativeElement.querySelector('.p-checkbox-box');
    if (oldIcon) {
      this.renderer.removeChild(this.elementRef.nativeElement, oldIcon);
    }
    if (!newIcon) {
      const component = createComponent(CustomIcon, {
        environmentInjector: this.environmentInjector,
      });
      this.renderer.addClass(component.location.nativeElement, 'p-element');
      this.renderer.addClass(
        component.location.nativeElement,
        'p-icon-wrapper'
      );
      this.renderer.appendChild(
        checkboxContainer,
        component.location.nativeElement
      );
    }
  }
}

Stackblitz 演示

© www.soinside.com 2019 - 2024. All rights reserved.