Обновление Angular Element Ref не работает при использовании кнопок Angular Material

Я пытаюсь обновить отключенное свойство кнопки с помощью директивы. Но наличие атрибута 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>

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

Спасибо,


person caden311    schedule 10.02.2020    source источник
comment
Мне нужно проверить, чтобы быть уверенным, и я не использую материальные вещи, но вы используете js vanilla nextElementSibling, который в этом случае ищет узел компонента DOM, поэтому он изящно терпит неудачу. Если вместо этого вы использовали renderer2, который является в любом случае лучший способ, чем он должен работать, или просто нажмите свойство [disabled] @Input напрямую и выполнить то же самое с помощью быстрого лога <mat-raised-button [disabled]="bool".....   -  person Chris W.    schedule 11.02.2020
comment
Спасибо за предложение по использованию Renderer. Если это лучшая практика, я буду использовать ее. Но я смог решить эту проблему, заключив ее в setTimeout. Я опубликую ответ. Я не мог использовать [disabled] напрямую, потому что он использует асинхронный вызов.   -  person caden311    schedule 11.02.2020
comment
Нет, чувак, избегай тайм-аута для тривиальных вещей. В лучшем случае использование ViewChild было бы лучшим путем, но в этом случае я бы предложил просто упростить себе все вместе, но по-прежнему использовать встроенные угловые механизмы, как в этом случае, просто поместив [disabled]="!hasPermission && this.hasPermissionJustDisable" на кнопку, должно сделать это, но рад, что вы нашли средство в любом случае.   -  person Chris W.    schedule 11.02.2020


Ответы (1)


Я смог решить эту проблему, обернув мою настройку disabled в 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;
                }
person caden311    schedule 10.02.2020