角度指令,用于处理可见性/启用给定配置



我有以下指令,用于处理从应用它的元素开始的所有子元素的可见性/启用。

ngAfterViewInit中,该指令检索向 Web API 提供组件名称属性和记录的用户角色的元素的配置。之后,配置将应用于与配置中的行匹配的所有元素。

import {
  Directive, Input,
  ElementRef, AfterViewInit, ViewContainerRef, Renderer2, DoCheck
} from '@angular/core';
import { CompConfig } from '../model/comp-config';
import { ConfigService } from '../services/config.service';
@Directive({
  selector: '[limsApplyConfig]'
})
export class ApplyConfigDirective implements AfterViewInit, DoCheck {

  config: CompConfig[];
  compName: string;
  constructor(
    private hostElement: ElementRef,
    private cs: ConfigService,
    private renderer: Renderer2
  ) { }
  @Input() set limsApplyConfig(compName: string) {
    this.compName = compName;
  }
  ngAfterViewInit(): void {
    // start with everything hidden: when a config will be received 
    // elements can be enabled following configuration
    this.renderer.addClass(this.hostElement.nativeElement, 'cfg-hidden');
    this.cs.getConfig(this.compName).subscribe(c => {
      this.renderer.removeClass(this.hostElement.nativeElement, 'cfg-hidden');
      this.config = c;
      this.config.forEach(cfg => {
        if (this.hostElement.nativeElement.querySelectorAll) {
          const inputCollection = this.hostElement.nativeElement.querySelectorAll('#' + cfg.ControlName);
          inputCollection.forEach(n => {
            // readonly is a property of inputs
            if (n.readOnly !== undefined) {
              n.readOnly = cfg.Disable;
            }
            // disabled is a property of buttons
            if (n.disabled !== undefined) {
              n.disabled = cfg.Disable;
            }
            if (cfg.Invisible) {
              this.renderer.addClass(n, 'cfg-hidden');
            }
          });
        }
      });
    });
  }
  ngDoCheck(): void {
    if (this.config && this.config.length > 0) {
      this.config.forEach(cfg => {
        if (this.hostElement.nativeElement.querySelectorAll) {
          const inputCollection = this.hostElement.nativeElement.querySelectorAll('#' + cfg.ControlName);
          inputCollection.forEach(n => {
            if (n.readOnly !== undefined) {
              n.readOnly = cfg.Disable;
            }
            if (n.disabled !== undefined) {
              n.disabled = cfg.Disable;
            }
            if (cfg.Invisible) {
              this.renderer.addClass(n, 'cfg-hidden');
            }
          });
        }
      });
    }
  }
}

对于元素的启用/禁用状态,我很难使指令赢得组件的特定逻辑。配置永远不会改变,但按钮/输入的状态会改变。

换句话说,如果应该禁用一个按钮,我想禁用它并保持禁用状态,即使组件的逻辑会启用它。不幸的是,我做不到。我尝试添加ngDoCheck生命周期钩子,但没有任何成功。

任何帮助将不胜感激

指令只计算一次,直到输入更改。如果您的组件正在更改指令的输入 [并且您的组件正在启用该按钮,但您仍然希望通过指令禁用它,请确保每次指令的输入更改时都执行您的订阅。如果我对您的问题的理解是正确的,那么让我们按如下方式更改代码 [请导入必要的类并原谅格式] -

    import {
  Directive, Input,
  ElementRef, AfterViewInit, ViewContainerRef, Renderer2, DoCheck
} from '@angular/core';
import { CompConfig } from '../model/comp-config';
import { ConfigService } from '../services/config.service';
@Directive({
  selector: '[limsApplyConfig]'
})
export class ApplyConfigDirective implements AfterViewInit, DoCheck {

  config: CompConfig[];
  compName: string;
  compName$: BehaviorSubject<string>;
  constructor(
    private hostElement: ElementRef,
    private cs: ConfigService,
    private renderer: Renderer2
  ) { 
   this.compName$ = new BehaviorSubject<string>(null);
 }
  @Input() set limsApplyConfig(compName: string) {
    this.compName$.next(compName);
  }
  ngAfterViewInit(): void {
    // start with everything hidden: when a config will be received 
    // elements can be enabled following configuration
    this.renderer.addClass(this.hostElement.nativeElement, 'cfg-hidden');
    this.compName$
        .pipe(
          mergeMap(cn => this.cs.getConfig(cn)),
          tap(config => {
            this.config.forEach(cfg => {
            if (this.hostElement.nativeElement.querySelectorAll) {
            const inputCollection = this.hostElement.nativeElement.querySelectorAll('#' 
            + cfg.ControlName);
          inputCollection.forEach(n => {
            // readonly is a property of inputs
            if (n.readOnly !== undefined) {
              n.readOnly = cfg.Disable;
            }
            // disabled is a property of buttons
            if (n.disabled !== undefined) {
              n.disabled = cfg.Disable;
            }
            if (cfg.Invisible) {
              this.renderer.addClass(n, 'cfg-hidden');
            }
          });
        }
      });
          })
        ).subscribe();
  }      
}

最新更新