#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>