typescript 无法访问Angular 12中的指令中的主机组件

1bqhqjot  于 2023-03-31  发布在  TypeScript
关注(0)|答案(2)|浏览(127)

bounty将在5天后过期。回答此问题可获得+100声望奖励。user1019042希望引起更多人关注此问题。

最近我们的项目从Angular 8升级到了Angular 12,从那以后我就无法访问指令中的主机组件引用了
下面是我在Angular 8中的指令

export class CardNumberMaskingDirective implements OnInit {

  unmaskedValue: string;

  constructor(private control: NgControl,
              private element: ElementRef,
              private _viewContainerRef: ViewContainerRef) {}

  ngOnInit() {
    this.hide(this.element.nativeElement);
  }

  @HostListener('focusout', ['$event.target'])
  hide(input) {
    const host = this._viewContainerRef['_view'].component;
    if (host['disableMask'] instanceof Function) {
      host['disableMask'](this.control.name);
      setTimeout(() => {
        this.unmaskedValue = input.value;
        const value = input.value.replace(/\s/g, '');
        if (value.length > MASKED_LENGTH) {
          const formatted = input.value.replace(MASKING_REGEXP, '●●●● ●●●● ●●●● ');
          this.control.valueAccessor.writeValue(formatted);
        }
      }, 0);
    }
  }

  @HostListener('focusin', ['$event.target'])
  show(input) {
    const host = this._viewContainerRef['_view'].component;
    const value = input.value.replace(/\s/g, '');
    if (value.length > MASKED_LENGTH) {
      this.control.valueAccessor.writeValue(this.unmaskedValue);
    }
    if (host['enableMask'] instanceof Function) {
      host['enableMask'](this.control.name);
    }
  }

}

在Angular V12中,我们没有_view,我必须使用**_hostLView**来访问组件引用。但如果我使用._viewContainerRef['_hostLView '].component,我仍然没有获得组件引用。
我在这里找到了一个类似的解决方案,但这里发布的解决方案https://stackoverflow.com/a/69706978对我不起作用(我没有得到组件参考)任何建议都非常感谢

4urapxun

4urapxun1#

没有通用的方法,另一种选择是使用常见的InjectionToken

export interface IComponent {}

export const token: InjectionToken<IComponent> = new InjectionToken<IComponent>('IComponent');

@Component({
providers: [{provide: token, useExisting: forwardRef(() => MyComponent1)}]
})
export class MyComponent1 implements IComponent {}

@Component({
providers: [{provide: token, useExisting: forwardRef(() => MyComponent2)}]
})
export class MyComponent2 implements IComponent {}

@Directive({})
export class MyDirective {
    constructor(@Inject(token) component: IComponent){}
}

您可以使用@Host()或/和@Self()使其更加严格。

oxiaedzo

oxiaedzo2#

您可以通过DI在指令中访问主机组件。
示例:

constructor(
 @Self() private readonly component: YourComponent
) {}

相关问题