以动态形式禁用输入验证

时间:2016-09-07 15:46:26

标签: angular angular2-forms

我有一个动态表单(使用angular.io动态表单实例plunkr做了一个示例),我想禁用此表单的输入,将其显示为只读信息。

所以我决定将disabled属性添加到问题模型中:

export class QuestionBase<T>{
  value: T;
  key: string;
  label: string;
  required: boolean;
  order: number;
  controlType: string;
  disabled?:boolean;

  constructor(options: {
      value?: T,
      key?: string,
      label?: string,
      required?: boolean,
      order?: number,
      controlType?: string,
      disabled?:boolean
    } = {}) {
    this.value = options.value;
    this.key = options.key || '';
    this.label = options.label || '';
    this.required = !!options.required;
    this.order = options.order === undefined ? 1 : options.order;
    this.controlType = options.controlType || '';
    this.disabled = options.disabled || false;
  }
}

然后我将disabled绑定到输入:

<input *ngSwitchCase="'textbox'" [disabled]="question.disabled" [formControlName]="question.key"
            [id]="question.key" [type]="question.type">

我收到警告,输入未被禁用:

It looks like you're using the disabled attribute with a reactive form directive. If you set disabled to true
      when you set up this control in your component class, the disabled attribute will actually be set in the DOM for
      you. We recommend using this approach to avoid 'changed after checked' errors.

      Example: 
      form = new FormGroup({
        first: new FormControl({value: 'Nancy', disabled: true}, Validators.required),
        last: new FormControl('Drew', Validators.required)
      });

所以我确实喜欢它在警告中写的并且我遇到了问题,验证器似乎不喜欢禁用的字段,即使它没有被标记为必需。

以下是我更改新QuestionControlService课程的内容:

@Injectable()
export class QuestionControlService {
  constructor() { }

  toFormGroup(questions: QuestionBase<any>[] ) {
    let group: any = {};

    questions.forEach(question => {
      group[question.key] = question.required ? new FormControl({value: question.value || '', disabled: question.disabled}, Validators.required)
                                              : new FormControl({value: question.value || '', disabled: question.disabled});
    });
    return new FormGroup(group);
  }
}

问题

disabled test字段已禁用,但无效,但由于尚未完全修改,因此该字段无法使用。

我的问题的Plunkr:http://plnkr.co/edit/qSDnD2xWWUwafyToDNX1?p=preview

2 个答案:

答案 0 :(得分:2)

我在github上提交了一个问题,结果发现这是理想的行为。

我的错误是检查每个字段的有效性,而不是检查整个表单。

答案 1 :(得分:0)

在GitHub上打开这个主题有几个问题。由于我遇到了同样的问题,我尝试构建一个自定义指令来提供所需的行为。

@Directive({
  selector: '[formControlName][dynamicDisable]'
})
export class DynamicDisable implements OnInit, OnChanges {
  constructor(
    @Optional() @Host() @SkipSelf() private parent: ControlContainer,
  ) { 

  }

  @Input() formControlName: string;  
  @Input() dynamicDisable: boolean;

  private ctrl: AbstractControl;

  ngOnInit() { 
    if(this.parent && this.parent["form"]) {
      this.ctrl = (<FormGroup>this.parent["form"]).get(this.formControlName);
    }
  }

  ngOnChanges() {
    if (!this.ctrl) return;

    if (this.dynamicDisable) {
      this.ctrl.disable();
    }
    else {
      this.ctrl.enable();
    }
  }
}

关注此问题的最新消息: https://github.com/angular/angular/issues/11379#issuecomment-246756547