只需尝试学习动态组件的使用。对于上下文(如果合适,还可以提供更好的解决方案的建议):应用程序接收问题(问题标题+可能的选项,包括多选,对/错,李克特量表,不限成员名额等)。
我的想法是使用动态组件来显示可以随问题而变化的部分:
<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
之类的功能不起作用-我认为这是因为父组件尚不了解子组件上正在发生的事情。
在这一点上,我真的不确定要去哪里-我需要从孩子那里冒出来并手动进行验证吗?我什至不确定要问的是正确的问题。
答案 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)→触摸元素时,将调用此方法