看这个例子Angular.io - 动态表单,它本质上是在运行时根据元数据构建表单。
有一些评论表明该示例尚未完成。
@Injectable()
export class QuestionService {
// Todo: get from a remote source of question metadata
// Todo: make asynchronous
getQuestions() {
...
这些是我完成它并清除错误消息所采取的步骤。
问题.service.ts
Changed getQuestions
异步返回问题。
Injectable()
export class QuestionService {
constructor(
private http: Http
) {}
getQuestions$() {
const url = 'https://api.myjson.com/bins/d0srd';
return this.http.get(url)
.map(response => response.json())
.map(questionMetadata => this.metadataToQuestions(questionMetadata))
.map(questions => questions.sort((a, b) => a.order - b.order))
}
private metadataToQuestions(questionMetadata) {
return questionMetadata.questions.map(this.toQuestion)
}
private toQuestion(elementData) {
// expand for additional control types
return new TextboxQuestion({
key: elementData.elementname,
label: elementData.displaytext,
value: elementData.elementvalue,
required: false,
order: elementData.sortorder
})
}
}
应用程序组件.ts
改变的变量questions
类型为可观察的,向模板添加了异步管道。
@Component({
...
template: `
<div>
<h2>Job Application for Heroes</h2>
<app-dynamic-form [questions]="(questions$ | async)"></app-dynamic-form>
</div>
`,
...
})
export class AppComponent implements OnInit {
questions$: Observable<any>;
constructor(
private questionService: QuestionService
) {}
ngOnInit() {
this.questions$ = this.questionService.getQuestions$();
}
}
动态表单.component.ts
更改了@Input变量questions
设置/获取样式,处理初始空值。
更改了创建表单的钩子ngOnInit
to ngOnChanges
处理问题的异步到达。
export class DynamicFormComponent implements OnChanges {
private _questions = [];
@Input()
set questions(value: any[]) {
this._questions = value || [];
}
get questions(): any[] {
return this._questions;
}
...
ngOnChanges() {
this.form = this.qcs.toFormGroup(this.questions);
}
}
动态表单问题.component.ts
添加额外的检查isValid
getter 以确保正在验证的控件存在。
export class DynamicFormQuestionComponent {
...
get isValid() { return this.form.controls[this.question.key]
? this.form.controls[this.question.key].valid : true; }
}