动态应用结构指令Angular 6

时间:2018-06-22 05:58:51

标签: javascript angular angular-directive angular6

我有结构指令uiIconWithTooltip。其代码:

@Directive({
  selector: '[uiIconWithTooltip]'
})
export class IconWithTooltipDirective implements OnInit {
  @Input('uiIconWithTooltip') iconWithTooltipOptions: IconWithTooltipOptions;

  wrapperContainer: ComponentRef<IconWithTooltipWrapperComponent>;

  constructor(
    public templateRef: TemplateRef<any>,
    public viewContainerRef: ViewContainerRef,
    public componentFactoryResolver: ComponentFactoryResolver
  ) {}

  ngOnInit() {
    const containerFactory = this.componentFactoryResolver.resolveComponentFactory(IconWithTooltipWrapperComponent);
    this.wrapperContainer = this.viewContainerRef.createComponent(containerFactory);

    this.wrapperContainer.instance.template = this.templateRef;
    if (this.iconWithTooltipOptions) {
      this.wrapperContainer.instance.iconClassName = this.iconWithTooltipOptions.iconClassName;
      this.wrapperContainer.instance.tooltip = this.iconWithTooltipOptions.tooltip;
      this.wrapperContainer.instance.placement = this.iconWithTooltipOptions.placement;
      this.wrapperContainer.instance.customTooltip = this.iconWithTooltipOptions.customTooltip;
      this.wrapperContainer.instance.container = this.iconWithTooltipOptions.container;
      this.wrapperContainer.instance.containerClass = this.iconWithTooltipOptions.containerClass;
      this.wrapperContainer.instance.delay = this.iconWithTooltipOptions.delay;
    }
  }
}

该指令要求对象带有选项:

export interface IconWithTooltipOptions {
  iconClassName: string;
  tooltip?: string;
  placement?: TooltipPlacementType;
  customTooltip?: ElementRef;
  container?: 'body';
  containerClass?: string;
  delay?: number;
}

它使用包装指令。 tempalte:

<ng-container *ngIf="iconClassName; else incomingTemplate">
  <div class="icon-with-tooltip-container">
    <ng-container *ngTemplateOutlet="incomingTemplate"></ng-container>
    <i aria-hidden="true" [container]="container" [tooltip]="tooltip" class="icon-with-tooltip" [ngClass]="iconClassName"></i>
  </div>
</ng-container>

<ng-template #incomingTemplate>
  <ng-container *ngTemplateOutlet="template"></ng-container>
</ng-template>

在这里,我用<div>将模板包装到<i>中。如果缺少iconClassName属性,我将仅渲染传入的临时模板。 我在ui-input-component中像这样使用该指令:

<input #inputElement *uiIconWithTooltip="getIconWithTooltipOptions()" />

getIconWithTooltipOptions()返回true时,应使用此工具提示。如果为假-不适用。 getIconWithTooltipOptions取决于验证服务,该服务验证输入并在输入无效时返回错误。如果输入有效getIconWithTooltipOptions-返回false。如果无效,请返回IconWithTooltipOptions对象。

getIconWithTooltipOptions() {
  const messages = this.getErrors();
  return messages && messages.length && <IconWithTooltipOptions>{
      iconClassName: 'fa fa-exclamation input-error-icon',
      tooltip: messages.join(' '),
      container: 'body',
    };
}

但是现在我面临着这样的问题,那就是行不通。因为我不能动态应用结构指令。使其存活的最佳解决方案是什么?现在,我认为唯一可能的解决方案是创建ui-tooltip组件。并像这样使用它:

<input #inputElement [value]="value" />
<ui-tooltip *ngIf="!isInputValid(inputElement)" text="Hi, i am an error"></ui-tooltip>

有什么方法可以通过结构指令来实现?

0 个答案:

没有答案