этот побочный эффект ключевого слова в угловой директиве

#javascript #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);
    }
  }
}
 

цвет-оттенок.компонент.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 не определен. Как я должен правильно использовать метод компонента в derictive

Ответ №1:

Вам нужно завернуть его в функцию со стрелкой, чтобы вы могли использовать 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>