【问题标题】:Disabled input validation in dynamic form以动态形式禁用输入验证
【发布时间】:2017-01-15 09:41:22
【问题描述】:

我有一个动态表单(使用 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

【问题讨论】:

    标签: angular angular2-forms


    【解决方案1】:

    在 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

    【讨论】:

    • 正如 kara 在我的 github 问题上所说,这种行为是设计使然。不应该一个一个地控制每个字段,否则在检查它是否有效之前,您必须检查该控件是否处于活动状态。
    【解决方案2】:

    我在github 上提交了一个问题,结果证明这是所需的行为。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-02-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多