动态组件是否可以在表单中用作表单字段,并且父组件仍可以进行验证?

时间:2019-12-14 00:54:51

标签: angular

只需尝试学习动态组件的使用。对于上下文(如果合适,还可以提供更好的解决方案的建议):应用程序接收问题(问题标题+可能的选项,包括多选,对/错,李克特量表,不限成员名额等)。

我的想法是使用动态组件来显示可以随问题而变化的部分:

<form #form="ngForm" novalidate>
      <app-question-response-configuration [question]="question"></app-question-response-configuration>
      <input type="text" ngModel name="test">
      <hr>
      <button
        disabled="{{ form.invalid ? 'disabled' : ''}}"
        type="submit"
        class="btn btn-primary">
        Submit</button>
    </form>

在动态组件中找到的html示例:

<div class="form-check" *ngFor="let choice of question.choices">
      <input
        ngModel
        required
        class="form-check-input"
        type="checkbox"
        value="{{ choice.id }}"
        name="questionChoices[]"
        id="choice-{{ choice.id }}"
      >
      <label class="form-check-label" for="choice-{{ choice.id }}">
        {{ choice.label }}
      </label>
    </div>

就显示而言,组件工厂针对不同的问题类型做了我想要做的事情。但是,诸如form.valid上的button之类的功能不起作用-我认为这是因为父组件尚不了解子组件上正在发生的事情。

在这一点上,我真的不确定要去哪里-我需要从孩子那里冒出来并手动进行验证吗?我什至不确定要问的是正确的问题。

1 个答案:

答案 0 :(得分:0)

您可以像这样使您的组件成为Form控件

import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';

@Component({
  selector: 'app-question-response-configuration',
  templateUrl: 'your-template-html' 
  ],
  providers: [
    {
      provide: NG_VALUE_ACCESSOR,
      useExisting: forwardRef(() => QuestionResponseConfigurationComponent),
      multi: true
    }
  ]
})
export class QuestionResponseConfigurationComponent implements ControlValueAccessor {

  @Input() question = "";

  // Function to call when the input is touched (when a star is clicked).
  onTouched = () => {};

  // Get the value of the form control
  get value(): number {
    return this.question;
  }

  // Set the value of the form control
  writeValue(value: number): void {
    this.value = value;
    this.onChange(this.value);
  }

  registerOnChange(fn: (rating: number) => void): void {
    this.onChange = fn;
  }

  registerOnTouched(fn: () => void): void {
    this.onTouched = fn;
  }

  // Allows Angular to disable the input.
  setDisabledState(isDisabled: boolean): void {
    // some logic
  }

}

对功能here的一些很好的解释:

  

onChange→要在UI更改时注册的回调函数

     

onTouch→用于在元素触摸上注册的回调函数   设置value(val:any)→设置元素的ngModel使用的值

     

writeValue(value:any)→如果在模型上以编程方式发生值更改,它将把该值写入视图

     

registerOnChange(fn:any)→更改UI中的值时,此方法将调用回调函数

     

registerOnTouch(fn:any)→触摸元素时,将调用此方法