如何防止单击Angular 4中的自定义按钮组件

tob*_*byb 2 typescript angular

tl; dr-如何获取click()myButton组件上的处理程序以兑现按钮的禁用状态?

我有一个自定义按钮组件,用于将外观和感觉相似的按钮组成组件,包括文本和FA图标。按钮组件将获得某些输入,包括其文本和一个标志,指示其是否已禁用。禁用后,它会正确显示(即,光标变暗且不吸烟),但其click()处理程序始终会收到点击。

我想我知道为什么会这样,但是我不知道如何解决。我试过Output() click = new EventEmitter<any>()在按钮组件上声明一个,以为Angular会以某种方式正确地将其连接起来,但这没有用。

我的按钮的使用者可以这样操作:

//foo.component.html
...
<my-button
  (click)="saveWidget()"
  [disabled]="shouldBeDisabled"
  type="{{buttonTypes.save}}">
</myButton>
...

//foo.component.ts
import { ButtonTypes } from './myButton';

export class FooComponent implements OnInit {
  buttonTypes = ButtonTypes;

  saveWidget() {
    //do some saving
  }

  get shouldBeDisabled() {
    return true; //Normally a real test in here
  }
  ...
}
Run Code Online (Sandbox Code Playgroud)

我的问题是,使用此按钮时,saveWidget()无论my-button的禁用状态如何,都将调用单击处理程序(即foo.component上)。

按钮组件看起来像这样:

export enum ButtonTypes {
  add,
  cancel,
  save,
}

@Component({
  selector: 'my-button',
  template: `<button [type]="tagType"
                [disabled]="disabled"
                [ngClass]="btnClasses">
                  <i *ngIf="hasLeft" class="fa" [ngClass]="iconCls" aria-hidden="true"></i>
                  <span class="hidden-xs hidden-sm">{{text}}</span>
                  <i *ngIf="hasRight" class="fa" [ngClass]="iconCls" aria-hidden="true"></i>
              </button>`
})
export class ButtonComponent implements OnInit {
  @Input() disabled = false;
  @Input('type') btnType: ButtonTypes;
  @Input() color?: ButtonColor;
  @Input() size?: ButtonSize;
  ...
}
Run Code Online (Sandbox Code Playgroud)

小智 5

您可以使用@HostBinding('class')和- :host选择器pointer-events: none根据您的shouldBeDisabled媒体资源来禁用点击:

//foo.component.scss

:host(.disabled) {
  // Disable click event.
  pointer-events: none;
}

:host(.enabled) {
  // No customizations.
}

//foo.component.html
...
<my-button
  (click)="saveWidget()"
  [disabled]="shouldBeDisabled"
  type="{{buttonTypes.save}}">
</myButton>
...

//foo.component.ts
import { ButtonTypes } from './myButton';

export class FooComponent implements OnInit {

  @HostBinding('class')
  get hostClass(): string {
    return this.shouldBeDisabled ? 'disabled' : 'enabled';
  }

  get shouldBeDisabled() {
    return true; //Normally a real test in here
  }
  ...
}
Run Code Online (Sandbox Code Playgroud)

我发现学习角度:有条件地向元素添加样式对于解决类似问题非常有用。