以基于模板的形式将所有表单控件设置为只读

时间:2017-11-01 20:39:25

标签: forms angular

我们有一个基于模板的表单,它使用各种Angular Material控件(matInput,mat-select等)。我们想为某些用户创建一个“只读”类型视图。我的直接想法是简单地检查用户的权限,然后遍历所有表单控件并将其设置为在需要时禁用。

这似乎适用于文本输入类型控件,但不适用于选择和复选框。另外,这会使控件变灰,这不一定是我们想要的。

有关如何最好地完成此任务的任何想法?也许以某种方式禁用表单中的键盘和鼠标输入可能是我们想要的但我不知道如何去做。

1 个答案:

答案 0 :(得分:0)

我认为这是可能的,但您必须检查所有控件类型,例如MatInput公开readonly属性,它允许我们创建将转换readonly状态的简单指令整个表格:

import {Directive, ContentChildren, QueryList, AfterContentInit, Input} from '@angular/core';
import {NgModel} from '@angular/forms';

@Directive({
    selector: 'form[readonly]'
})
export class FormReadonlyDirective implements AfterContentInit
{
    @ContentChildren(NgModel)
    public inputs:QueryList<NgModel>;

    private controls:any[];

    private _readonly:boolean = false;

    public ngAfterContentInit():void
    {
        this.controls = this.getControls();

        this.inputs.changes.subscribe(() =>
        {
            this.setReadonly(this.readonly);
        });

        this.setReadonly(this.readonly);
    }

    @Input()
    public get readonly():boolean
    {
        return this._readonly;
    }

    public set readonly(value:boolean)
    {
        this._readonly = value != null && value !== false && `${value}` !== 'false';
        this.setReadonly(value);
    }

    private setReadonly(value:boolean):void
    {
        if(this.controls != null)
        {
            this.controls.forEach(control =>
            {
                //todo: check
                control.readonly = value;
            });
        }
    }

    private getControls():any[]
    {
        return this.inputs.map(control => control.valueAccessor);
    }
}

未经测试,但您明白了。