使用角度形式将元素值作为JSON形成

时间:2018-11-02 07:02:06

标签: javascript json angular typescript angular-reactive-forms

我正在使用Angular dynamic form

进行Angle 6应用程序

在这里,我做了一个嵌套的输入字段,其中在初始阶段将有两个输入文本框,并且在单击添加按钮后,每次单击添加按钮时,都会添加下两个输入框。

在这里一切正常。

在这里,我已将 question-service.ts 中的值用作

  new TextboxQuestion({
  elementType: "textbox",
  class: "col-12 col-md-4 col-sm-12",
  key: "project_name",
  label: "Project Name",
  type: "text",
  value: '',
  required: true,
  order: 1
  }),

  new TextboxQuestion({
  elementType: "textbox",
  class: "col-12 col-md-4 col-sm-12",
  key: "project_desc",
  label: "Project Description",
  type: "text",
  value: '',
  required: true,
  order: 2
  }),
  new ArrayQuestion({
    key: 'myArray',
    value: '',
    order: 3,
    children: [
      new TextboxQuestion({
      elementType: "textbox",
      class: "col-12 col-md-4 col-sm-12",
      key: "property_one",
      label: "Property One",
      type: "text",
      value: '',
      required: true,
      order: 3
      }),
      new TextboxQuestion({
      elementType: "textbox",
      class: "col-12 col-md-4 col-sm-12",
      key: "property_two",
      label: "Property Two",
      type: "text",
      value: '' ,
      required: true,
      order: 4
      })
    ]
  })

我需要更改,就像每个数据都应来自json,

  jsonData: any = [
    {
      "elementType": "textbox",
      "class": "col-12 col-md-4 col-sm-12",
      "key": "project_name",
      "label": "Project Name",
      "type": "text",
      "value": "",
      "required": true,
      "order": 1
    },
    {
      "elementType": "textbox",
      "class": "col-12 col-md-4 col-sm-12",
      "key": "project_desc",
      "label": "Project Description",
      "type": "text",
      "value": "",
      "required": true,
      "order": 2
    },
    {
      "elementType": "array",
      "key": "myArray",
      "value": "",
      "order": "3",
      "children": [
        {
          "elementType": "textbox",
          "class": "col-12 col-md-4 col-sm-12",
          "key": "property_one",
          "label": "Property One",
          "type": "text",
          "value": "",
          "required": true,
          "order": 3
        },
        {
          "elementType": "textbox",
          "class": "col-12 col-md-4 col-sm-12",
          "key": "property_two",
          "label": "Property Two",
          "type": "text",
          "value": "",
          "required": true,
          "order": 4
        }
      ]
    }
  ];

Stackblitz 没有 JSON:

https://stackblitz.com/edit/angular-x4a5b6-xcychx

使用 JSON的Stackblitz

https://stackblitz.com/edit/angular-x4a5b6-u6ecpk

加载JSON时,需要在stacblitz链接中发生没有json的情况。

我在getQuestions()内给出了以下内容,

 getQuestions() {

    console.log(this.jsonData);

    let questions: any = [];

    this.jsonData.forEach(element => {
      if (element.elementType === 'textbox') {
        questions.push(new TextboxQuestion(element));
      } else if (element.elementType === 'array') {
        questions.push(new ArrayQuestion(element));
      }
    });

    return questions.sort((a, b) => a.order - b.order);
  }
}

对于正常的文本框,它可以工作,但是对于子文本框,则不能单击添加按钮(未显示文本框),而不会添加子文本框。

请帮助我实现与link 1中发生的相同结果,也需要在link 2中使用JSON时发生。。并且也不要在任何以核心角度出现的事情中包含任何第三方库

2 个答案:

答案 0 :(得分:3)

@@很多,当您拥有数组类型时,必须在推入数组之前创建子代。

...
} else if (element.elementType === 'array') {
    let children:any[]=[]; //declare children
    //each children of element fill our array children
    element.children.forEach(e=>{
       if (e.elementType === 'textbox') {
         children.push(new TextboxQuestion(e));
       }
    })
    //Hacemos un push not of element else element + the property children
    //changed (it will be the array created)
    questions.push(new ArrayQuestion({...element,children:children}));
}

答案 1 :(得分:1)

您必须添加新的类型“复选框” <​​/ p>

export class CheckBoxQuestion extends QuestionBase<string> {
  controlType = 'checkbox';
  type: boolean;

  constructor(options: {} = {}) {
    super(options);
  }
}

并更改动态表单问题

<div [formGroup]="form">
    <!--the label only show if it's NOT a checkbox --->
    <label *ngIf="question.controlType!='checkbox'" [attr.for]="question.key">{{question.label}}</label>

  <div [ngSwitch]="question.controlType">
    ...
    <!--add type checkbox-->
    <ng-container *ngSwitchCase="'checkbox'">
    <input  [formControlName]="question.key" type="checkbox"
            [id]="question.key" >
                <label [attr.for]="question.key">{{question.label}}</label>

            </ng-container>
    ...
  </div> 

并询问服务以考虑新复选框

else if (e.elementType === 'checkbox') {
            children.push(new CheckBoxQuestion(e));
          }

更新 如果我们要添加更多的验证器,请查看question.service.ts的函数“ toFormGroup”

toFormGroup(questions: QuestionBase<any>[]) {
    let group: any = {};

    questions.forEach(question => {
      if (question.controlType=="array") {
         group[question.key]=new FormArray([]);
      }
      else {
        //create an array of "validators"
        let validators:any[]=[];
        //If question.required==true, push Validators.required
        if (question.required && question.controlType!='checkbox')
            validators.push(Validators.required);
        //...add here other conditions to push more validators...
        group[question.key] = new FormControl(question.value || '',validators);
      }
    });
    return new FormGroup(group);
  }

更新两个 也需要更改questionbase.ts,以添加此属性

export class QuestionBase<T> {
  value: T;
  ...
  maxlength:number;
  minlength:number;

  constructor(options: {
      value?: T,
      ....
      minlength?:number,
      maxlength?:number,
      controlType?: string,
      children?:any
    } = {}) {
    this.value = options.value;
    ....
    this.minlength = options.minlength;
    this.maxlength = options.maxlength;
    ...
  }
}

要查看有关form.get(question.key).errors的错误,例如

  <div class="errorMessage" 
     *ngIf="form.get(question.key).errors?.required">
    {{question.label}} is required
  </div>

提示:了解您的错误使用情况

{{form.get(question.key).errors|json}}

请参见forked stackblitz