首先,我们需要问自己为什么要创建一种新型的按钮组件,而我们已经有了一个原生的按钮组件。可能是这样的:
- 利用一些 Angular 助手,例如动画
- 在执行某些点击处理程序期间禁用按钮。
- 进度指示。
- ...
如果可以使用 本机按钮(解决方案 0)解决要求,请坚持下去。否则,继续。
在创建可重用文件之前,我们需要了解两件重要的事情
按钮组件:
K1 只能禁用有限的 HTML 元素子集,
https://html.spec.whatwg.org/multipage/semantics-other.html#disabled-elements。这
表示即使元素被禁用也会触发点击处理程序。
K2 在 Angular 中,无法从内部控制外部事件
里面。 https://github.com/angular/angular/issues/12630
解决方案 1. 点击处理程序作为输入
要解决 K2,您可以使用 @Input 回调而不是
事件绑定。然后你可以从内部控制它,并且
您甚至可以访问内部回调的结果。它
看起来像:
<my-button [myClick]="doIt"> or with arguments <my-button [myClick]="doIt.bind(1)">
@HostListener('click') onClick(event) {
this.myClick();
}
既然你可以完全控制回调,你可以省略调用
当它是disabled 时。
需要此解决方案的一个问题是带有进度指示的按钮。当您完全控制回调时,库按钮可以开始/停止进度条的动画,甚至可以通过在进行中禁用它来阻止其他点击。将其与本模块中的进度按钮进行比较
https://github.com/michaeldoye/mat-progress-buttons 你需要的地方
每个按钮实例的启动/停止动画!
缺点:非标准外观。您的图书馆用户会喜欢为什么会这样
回调输入而不是事件绑定...
解决方案 2. CSS
您可以尝试使用 CSS pointer-events:none 解决 K1。它
可以在表面上工作,阻止用户鼠标触发的点击
事件。但是,您仍然可以务实地单击
按钮。 myButton.click() 在按钮被“禁用”时仍会触发。
缺点:“已禁用”元素仍为 clickable。可能,不适合
您的图书馆用户正在编写自动化测试。
解决方案 3. 组件化原生按钮
要使禁用和事件按预期工作,您需要应用
组件直接放在 HTML 按钮元素上。在 Angular Material 中,它看起来
喜欢<button mat-button>,
https://github.com/angular/components/blob/master/src/material/button/button.ts#L66
而且很简单:
@Component({
selector: 'button[my-button]',
template: '<ng-content></ng-content>'
})
并使用它:
<button my-button (click)="doIt()" [disabled]="isDisabled">Save</button>
现在当my-button 被禁用时不会触发点击事件。
缺点:必须有原生按钮,my-button 看起来更像
是一个指令而不是一个组件。
结论
我建议使用最符合要求的解决方案,而不是 CSS hack 解决方案。