【问题标题】:how to make dynamic form from API response in angular 7?如何从 Angular 7 中的 API 响应中制作动态表单?
【发布时间】:2019-04-22 18:08:04
【问题描述】:

我正在研究 Angular 7 中的动态形式。我遵循了 Angular 官方网站上提到的方式。我成功实施了该教程,但我的情况不同。表单中会有什么样的输入,它的所有属性都来自 API 响应

这是带来我的数据的服务功能。 请注意:基于 API 数据,我将填充我的问题数组,现在我使用虚拟数据只是为了确保流程正常工作。这就是我的 question.service.ts 的样子

public response : QuestionBase<any>[] =[];      
getQuestions(id) {
  this.http.get(this.url+'selectAllFieldDetails/'+id)
.pipe(map(
( response: Response) => {
    let data = response;
    console.log(data);


   let questions: QuestionBase<any>[] = [

      new DropdownQuestion({
        key: 'brave',
        label: 'Bravery Ratings',
        class:'form-control fis-form-control',
        formclass:'',
        options: [
          {key: 'solid',  value: 'Solid'},
          {key: 'great',  value: 'Great'},
          {key: 'good',   value: 'Good'},
          {key: 'unproven', value: 'Unproven'}
        ],
        required: true,
        order: 2
      }),

      new TextboxQuestion({
        key: 'process',
        label: 'Process name',
        value: 'IT ',
        class:'form-control fis-form-control',
        formclass:'',
        required: true,
        order: 1
      }),


    ];
    this.response =  questions.sort((a, b) => a.order - b.order);
   }
  ));
  console.log(this.response);
  return this.response;
}

但问题是函数在 API 响应之前返回并且它返回空数组。这是我从 create-ticket.component.ts 调用的方式

ngOnInit() {
  this.questions = this.service.getQuestions(24);
  console.log(this.questions);
}

不知何故,我尝试先获取 API 响应并将其存储在某个变量中,然后调用此函数 this.service.getQuestions(24);但随后它显示错误

Error: Cannot find control with name: 'process'
at _throwError (forms.js:1775)
at setUpControl (forms.js:1683)
at FormGroupDirective.push../node_modules/@angular/forms/fesm5/forms.js.FormGroupDirective.addControl (forms.js:4532)
at FormControlName.push../node_modules/@angular/forms/fesm5/forms.js.FormControlName._setUpControl (forms.js:5030)
at FormControlName.push../node_modules/@angular/forms/fesm5/forms.js.FormControlName.ngOnChanges (forms.js:4980)
at checkAndUpdateDirectiveInline (core.js:9239)
at checkAndUpdateNodeInline (core.js:10507)
at checkAndUpdateNode (core.js:10469)
at debugCheckAndUpdateNode (core.js:11102)
at debugCheckDirectivesFn (core.js:11062)

Formgorup 数据保持为空。 请帮我解决这个问题。 在此先感谢

【问题讨论】:

  • 请提供所有代码,甚至最好提供一个堆栈闪电战,以最大限度地减少故障排除。
  • 问题是:您没有订阅获取请求以启动请求。

标签: angular angular7 angular-reactive-forms dynamic-forms form-control


【解决方案1】:

所以,经过长时间的研发,我终于做到了。基本上有两个问题

  1. 服务中的函数在 API 响应之前响应
  2. 在数据投入使用之前创建表单

所以对于第一个问题,我在角度中使用了async await 功能的概念

在 create-ticket.component.ts 中我们添加了 async 和 await 像这样。

async ngOnInit() {
    this.questions = await this.service.getQuestionss(24);
    if(this.questions.length>0){
       this.showForm=true;
    }
}

在服务中我们返回一个承诺

async getQuestionss(id): Promise<any> {
     this.responses = await this.apiServce.getAllInputFields(id).toPromise();
}

它作为一个 Promise 响应,所以它等到 api 响应。 this.apiservice.getAllInputFields(id) 只是来自服务器的 http api 调用。

对于第二个问题,我只使用了一个小解决方案。我在表单中添加了 *ngIf,所以当 api 响应数据时,只有表单开始构建。

<app-dynamic-forms *ngIf="showForm" [questions]="questions"></app-dynamic-forms>

就是这样,问题解决了。

【讨论】:

    【解决方案2】:

    基于 stackblitz 的过时信息

    您应该始终订阅异步调用,以便它 被执行

    ngOnInit() {
      this.questions = this.service.getQuestions(24).subscribe(result => {
                    do something with result }, 
          err => { something went wrong });
    }
    

    这是一个基于你的堆栈闪电战: https://stackblitz.com/edit/angular-h8zakj?embed=1&file=src/app/question.service.ts

    正如我所说,您的 setTimeout 存在问题。无法在您想要的地方访问数据。

    【讨论】:

    • QuestionBase[] 类型上不存在属性订阅。这是我的问题库界面。导出类 QuestionBase { 值:T;键:字符串;标签:字符串;必需:布尔值;订单号;类:字符串;控制类型:字符串;表单类:字符串;构造函数(选项:{值?:T,键?:字符串,标签?:字符串,必需?:布尔,顺序?:数字,类?:字符串,formclass?:字符串,控件类型?:字符串} = {}){ } }
    • 是的,他应该将 thiis.http.get 调用作为他的服务中的 observable 返回并更改返回类型。反正他混了很多不完整的东西。这就是我请求模式代码的原因
    • 他最终应该将getQuestions(id) { this.http.get(this.url+'selectAllFieldDetails/'+id) .pipe(map( ... 作为可观察对象返回。现在他需要重新观察他的虚拟数据以使其正常工作
    • stackblitz.com/edit/angular-ytkydp 这是编辑器的网址。你可以看到我面临的问题。我调用了 settimeout 函数而不是 http 调用,因为行为是相同的。如果您删除 settimeout 功能,则会出现表单。
    猜你喜欢
    • 2020-04-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-31
    • 2020-04-18
    • 1970-01-01
    • 1970-01-01
    • 2019-12-22
    相关资源
    最近更新 更多