Angular - предотвращение события нажатия на отключенные кнопки - PullRequest
1 голос
/ 20 февраля 2020

Я пытаюсь предотвратить событие нажатия на отключенных кнопках, другими словами, запретить некоторым пользователям, удаляющим отключенный атрибут, вызывать какое-либо действие.

На данный момент у меня есть следующий код для этого:

<button [disabled]="someCondition" (click)="executeAction()">Execute action</button>
executeAction(): void {
  if (this.someCondition) return;

  // ...
}

Работает, но это не очень хорошее решение, так как я должен сделать это для ВСЕХ кнопок в моем приложении (и, поверьте мне, легко забыть это сделать и даже Линтер здесь не может помочь).

В поисках более надежного решения я подумал, что directive может помочь мне:

import { Directive, HostListener, Input, Renderer2, ElementRef } from '@angular/core';

@Directive({
  selector: 'button'
})
export class ButtonDirective {
  @Input() set disabled(value: boolean) {
    this._disabled = value != null;
    this.renderer2.setAttribute(this.elementRef.nativeElement, 'disabled', `${this._disabled}`);
  }

  private _disabled: boolean;

  constructor(
    private readonly elementRef: ElementRef,
    private readonly renderer2: Renderer2
  ) { }

  @HostListener('click', ['$event'])
  onClick(mouseEvent: MouseEvent) {
    // nothing here does what I'm expecting
    if (this._disabled) {
      mouseEvent.preventDefault();
      mouseEvent.stopImmediatePropagation();
      mouseEvent.stopPropagation();

      return false; // just for test
    }
  }
}
<button [disabled]="someCondition" (click)="executeAction()">Execute action</button>
executeAction(): void {
  console.log('still being called');
}

... однако это абсолютно ничего не делает. Это не предотвращает событие click. Есть ли какое-либо решение, которое мне не нужно контролировать само действие в его вызове?

STACKBLITZ

Ответы [ 2 ]

0 голосов
/ 20 февраля 2020

В вашей директиве вы можете сделать что-то подобное. Вы можете достичь этого, добавив прослушиватель событий к родителю на этапе захвата.

ngOnInit() {
    this.elementRef.nativeElement.parentElement.addEventListener('click',(e) => {
      if(this._disabled && e.target.tagName === 'BUTTON') {
        e.stopImmediatePropagation();
        e.stopPropagation();
      }
    }, true);
  }

Вы можете удалить прослушиватель в onDestroy

0 голосов
/ 20 февраля 2020

Предотвращение события щелчка на отключенных кнопках

Если атрибут disabled присутствует, щелчок не произойдет.

Когда пользователь решает использовать devtools

Однако, если пользователь редактирует HTML и удаляет отключенный атрибут вручную, тогда произойдет щелчок. Вы можете попробовать выполнить проверку, как вы предлагали, но браузер является небезопасной средой. Пользователь по-прежнему сможет выполнять любой код от имени веб-страниц независимо от любых проверок frontend , которые вы можете вставить.

...