使用 Angular 材质按钮时更新 Angular Element Ref 损坏

Posted

技术标签:

【中文标题】使用 Angular 材质按钮时更新 Angular Element Ref 损坏【英文标题】:Updating Angular Element Ref broken when using Angular Material Buttons 【发布时间】:2020-05-26 05:14:30 【问题描述】:

我正在尝试通过指令更新按钮上的 disabled 属性。但是在按钮上有mat-raised-button 属性不会让按钮被设置为禁用。这是我的 html

<button  mat-raised-button color="primary" *hasPermission="PERMISSION_TYPES.Admin; justDisable: true" >
    DISABLE USER
</button>

然后在我的结构指令中我禁用按钮。

@Directive(
    selector: '[hasPermission]', // tslint:disable-line
)
export class HasPermissionDirective implements OnInit 
    @Input() public hasPermission;
    @Input() public hasPermissionJustDisable = false;
    constructor(
        private viewContainer: ViewContainerRef,
        private templateRef: TemplateRef<any>,
        private permissionService: PermissionValidationService,
        private elementRef: ElementRef<any>) 
    

    ngOnInit(): void 
        this.checkPermission();
    

    private checkPermission() 
        this.permissionService.hasValidPermission(this.hasPermission)
            .then((hasPermission) => 
                if (!hasPermission && !this.hasPermissionJustDisable) 
                    this.viewContainer.clear();
                    return;
                
                if (!hasPermission && this.hasPermissionJustDisable) 
                    this.viewContainer.createEmbeddedView(this.templateRef);
                    this.elementRef.nativeElement.nextElementSibling.setAttribute('disabled', 'disabled');
                    return;
                
                this.viewContainer.createEmbeddedView(this.templateRef);
            );
    

问题是,它不会禁用按钮。但如果我像这样删除了mat-raised-button

            <button  *hasPermission="PERMISSION_TYPES.Admin; justDisable: true" >
                DISABLE USER
            </button>

然后按钮被禁用。它必须与角度材料如何渲染这些有关。任何帮助将不胜感激。

谢谢,

【问题讨论】:

我必须进行测试才能确定,我不使用材料,但你使用的是 js vanilla nextElementSibling,在这种情况下它正在寻找一个组件 DOM 节点,所以它优雅地失败了.相反,如果您使用renderer2(即the better way anyway),那么它应该可以工作,或者直接点击[disabled] @Input 属性并使用快速布尔&lt;mat-raised-button [disabled]="bool"..... 完成同样的事情 感谢关于使用 Renderer 的建议。如果这是更好的做法,我会使用它。但是我能够通过将它包装在 setTimeout 中来解决它。我会发布答案。我无法直接使用 [disabled],因为它使用异步调用。 不,人避免设置超时的琐碎事情。最多使用ViewChild 将是更好的路线,但对于这种情况,我建议只是让你自己更轻松,但仍然使用内置的角度机制,比如在这种情况下只需将[disabled]="!hasPermission &amp;&amp; this.hasPermissionJustDisable" 放在按钮上就可以了但很高兴你找到了任何一种方法。 【参考方案1】:

我能够通过将我的禁用设置包装在 SetTimeout 中来解决它,如下所示:

if (!hasPermission && this.hasPermissionJustDisable) 
                    this.viewContainer.createEmbeddedView(this.templateRef);
                    // Timeout is required for some rendering quark with angular material buttons..
                    setTimeout(() => 
                        this.renderer.setAttribute(this.elementRef.nativeElement.nextElementSibling, 'disabled', 'disabled');
                    );
                    return;
                

【讨论】:

以上是关于使用 Angular 材质按钮时更新 Angular Element Ref 损坏的主要内容,如果未能解决你的问题,请参考以下文章

Angular:使用指令禁用材质按钮不起作用

使用Material数据表时,dataSource.connect不是函数

在 Angular 2 材质中添加粘性 FAB

Angular:材质按钮遵循标题大小

Angular:在关闭浏览器窗口之前显示材质弹出窗口

在 Angular 材质表上调用 renderRows()