首页 > 解决方案 > Angular 指令中的 this 关键字副作用

问题描述

我有一个 Angular 指令,它用于其中一个组件。问题是当我将组件的方法作为指令的参数传递,然后在指令中启动时,this关键字指的是组件以外的东西。

@Directive({
  selector: "[listenTo]"
})
export class ListenToDirective {
  @Input('listenTo') listenerConfiguration: {event: string, listener: (event?: Event) => any, global?: boolean }[];
  constructor(private elementRef: ElementRef, private renderer: Renderer2, private userInputService: UserInputService)
  {}

  private subscriptions: Subscription[] = [];
  ngAfterViewInit() {
    for (const setup of this.listenerConfiguration) {
      if (setup.global) {
        this.subscriptions.push(
          this.userInputService.subscribe(setup.event).subscribe(setup.listener)
        );
      } else this.renderer.listen(this.elementRef.nativeElement, setup.event, setup.listener);
    }
  }
  ngOnDestroy() {
    for (const sub of this.subscriptions) {
      sub.unsubscribe();
    }
  }
}

听指令.ts

@Component({
  selector: 'color-hue',
  templateUrl: './color-hue.component.html',
  styleUrls: ['./color-hue.component.scss']
})
export class ColorHueComponent {

  @Output('hue') hueOutput = new EventEmitter<number>();
  @ViewChild('HueContainer') hueContainer: ElementRef<Element>;

  isMoving = false;
  pickerPosition = 0;
  pickerColorHue = 0;

  onContainerMouseDown() {
    console.log("hello");
    this.isMoving = true;
  }

  onContainerMouseMove(event: MouseEvent) {
    if (this.isMoving) {
      console.log(event.clientY);
      const box = this.hueContainer.nativeElement.getBoundingClientRect();
      const beginY = box.y;
      const mouseY = event.clientY;
      this.pickerPosition = Math.max(0, Math.min(box.height, mouseY - beginY));
      this.hueOutput.emit(this.pickerColorHue = Math.min(this.pickerPosition / box.height, 0.999) * 360);
    }
  }
}

color-hue.component.ts

<div class="hue">
  <div class="hue-pointer-container" #HueContainer
       [listenTo]=
         "[
            { event: 'mousemove', listener: onContainerMouseMove, global: true }
         ]"
    >
    <
  </div>
</div>

color-hue.component.html

所以在指令中,this.isMoving 是未定义的。我应该如何正确使用派生词中的组件方法

标签: javascriptangular

解决方案


您需要将其包装在箭头函数中,以便您可以使用this.

在经典函数表达式中,this 关键字根据调用函数的上下文绑定到不同的值。而箭头函数在其词法范围内使用 this 的值。这导致了非常不同的行为。

读这个

这样做应该有效:

onContainerMouseMove() {
    return (event: MouseEvent) => {
      console.log(this.isMoving);
      if (this.isMoving) {
        console.log(event.clientY);
        const box = this.hueContainer.nativeElement.getBoundingClientRect();
        const beginY = box.y;
        const mouseY = event.clientY;
        this.pickerPosition = Math.max(
          0,
          Math.min(box.height, mouseY - beginY)
        );
        this.hueOutput.emit(
          (this.pickerColorHue =
            Math.min(this.pickerPosition / box.height, 0.999) * 360)
        );
      }
    };
  }

<div class="hue">
  <div class="hue-pointer-container" #HueContainer [listenTo]="[
            { event: 'mousemove', listener: onContainerMouseMove(), global: true }
         ]">
  </div>
</div>

推荐阅读