无法使用此角度反应表单:数据绑定错误,存储/获取数据未正确填充表单等

时间:2018-06-15 14:24:34

标签: angular forms data-binding angular-reactive-forms

所以这是一个Angular 5应用程序。对于这个问题,我查看了Angular.io基本文档/ exmaple应用程序(可以在这里找到:https://angular.io/guide/reactive-forms),但我似乎无法在我的工作(正确)上工作结束:(。我也想说我对Angular来说是非常新的。

所以我打破这篇文章,解释我想要的东西,尝试用打印屏幕(以及我的评论)显示它,然后显示我的组件和代码的代码。服务,以便您可以全面了解我想要什么,我有什么,可能是什么错。此外,不要担心到处都是可怕的布局,现在不重要(它只需要工作)。

所以它是一个从Sharepoint获取/创建内容的应用程序,但是如果你不了解Sharepoint的任何内容,那么理解这个问题并不是一个问题。

首先,我有这个页面,您可以登录:enter image description here

用户将登录特定的Sharepoint租户/站点,然后被重定向到我的第一个视图,我希望用户能够动态地在表单中制作内容类型。我的意思是理想情况下,显示一个空的,他可以添加"内容类型"随心所欲。内容类型可以被视为"类"在正常编程中。

以下是我的内容类型视图,我希望用户能够制作多个:enter image description here

首先,这会产生一些错误:

ERROR Error: Cannot find control with path: 'contentTypesInputFields -> 0 -> Name'
    at _throwError (forms.js:2432)
    at setUpControl (forms.js:2300)
    at FormGroupDirective.addControl (forms.js:6658)
    at FormControlName._setUpControl (forms.js:7308)
    at FormControlName.ngOnChanges (forms.js:7221)
    at checkAndUpdateDirectiveInline (core.js:12365)
    at checkAndUpdateNodeInline (core.js:13893)
    at checkAndUpdateNode (core.js:13836)
    at debugCheckAndUpdateNode (core.js:14729)
    at debugCheckDirectivesFn (core.js:14670)

当我点击任何内容或在任何地方键入任何字符/字符串时,似乎"循环"通过我的控件(它似乎无法找到),它最终看起来像这样(就像它应该):

enter image description here

它循环的错误与上面相同,只是这次也适用于' Group'和' ContentTypeInherit'。这张图片与之前的图片有一些区别:现在它说"内容类型#1"还有我的"继承自内容类型:"标签&选择该节目(并填写选择)。

我现在要点击按钮添加一个新的"测试行",第一张图片是点击按钮后立即显示的图片,第二张图片显示了在输入一对夫妇后的样子事情(所以它可以再次循环错误):

第一张图片:
enter image description here

第二张图片:
enter image description here

当我点击我的"删除"按钮它应该删除"内容类型"它被点击的字段,所以如果我点击"删除"内容类型#2下的按钮应该删除那个,而不是其他。现在这个按钮什么都不做(但我尝试编码,稍后再看)。

好的,现在我将分享我的整个代码文件:

我的组件HTML:

<form [formGroup]="contentTypeForm" (ngSubmit)="onSubmit($event)">
  <div formArrayName="contentTypesInputFields">
      <div *ngFor="let currentContentType of contentTypesInputFields.controls; let i=index" [formGroupName]="i">
        <h4>Content Type #{{i + 1}}</h4>
        <ul>
          <li class="form-group">
            <label>Content Type Name:</label>
            <input class="json-input form-control" type="text" formControlName="Name">
          </li>
          <li class="form-group">
            <label>Content Type Group:</label>
            <input class="json-input form-control" type="text" formControlName="Group">
          </li>
          <li class="form-group" *ngIf="contentTypeDropDown.length != '0'">
            <label>Inherit from Content Type:</label>
            <select class="json-input form-control" formControlName="ContentTypeInherit" *ngIf="!checkboxCTchecked">
              <option *ngFor="let ct of contentTypeDropDown" [value]="ct.name">{{ ct.name }}</option>
            </select>
            <!--
            <input class="json-input form-control" type="text" formControlName="ContentTypeInherit" *ngIf="checkboxCTchecked" placeholder="Cannot be left empty!">
            -->
          </li>
        </ul>
        <button type="button" (click)="removeContentTypeInputFields(currentContentType)">Remove</button>
      </div>
      <div>
        <!--
        <button type="submit" [disabled]="contentTypeForm.pristine">Save</button>
        <button type="button" [disabled]="contentTypeForm.pristine" (click)="revertData()">Revert</button>
        -->
        <button type="submit">Save</button>
        <button type="button" (click)="revertData()">Revert</button>
      </div>
  </div>
</form>
<div>
  <button type="button" (click)="addContentTypeInputFields()">Click here to add a new test row!</button>
</div>  

我的组件TS:

import { Component, OnInit, OnChanges } from '@angular/core';
import { DataServicesService } from '../data-services.service';
import { ContentType } from '../ContentType';
import { FormGroup, FormBuilder, FormArray } from '@angular/forms';

@Component({
  selector: 'app-content-type-detail',
  templateUrl: './content-type-detail.component.html',
  styleUrls: ['./content-type-detail.component.css']
})
export class ContentTypeDetailComponent implements OnInit, OnChanges {

  contentTypeForm: FormGroup;

  contentTypeInputFieldsArrayOnLoad: ContentType[] = [
    {
      id: '',
      name: '',
      group: '',
      contentTypeInherit: ''
    }
  ];
  contentTypeInputFieldsArray: ContentType[] = this.contentTypeInputFieldsArrayOnLoad.slice();
  contentTypeDropDown: ContentType[] = [];

  checkboxCTchecked = false;

  constructor(
    private dataService: DataServicesService,
    private fb: FormBuilder
  ) {
    this.createForm();
  }

  ngOnInit() {

  }

  ngOnChanges() {
    this.rebuildForm();
  }

  public createForm() {
    const tt2 = this.dataService.getData('ContentTypesDropDown');
    if (this.dataService.getData('ContentTypesDropDown') != null) {
      this.dataService.getData('ContentTypesDropDown').subscribe(
        res => this.contentTypeDropDown = JSON.parse(res)
      );
    }

    let data = null;
    if (this.dataService.getData('ContentTypes') != null) {
      this.dataService.getData('ContentTypes').subscribe(
        res => data = JSON.parse(res)
      );
    }

    if (data != null) {
      const arr = JSON.parse(data);
      this.contentTypeInputFieldsArrayOnLoad = arr;
      this.contentTypeInputFieldsArray = this.contentTypeInputFieldsArrayOnLoad.slice();
    }

    this.contentTypeForm = this.fb.group({
      // contentTypesInputFields: this.fb.array([])
      contentTypesInputFields: this.fb.array(this.contentTypeInputFieldsArrayOnLoad)
    });
    const tt = this.contentTypesInputFields;
  }

  public rebuildForm() {
    this.setContentTypes(this.contentTypeInputFieldsArray);
  }

  get contentTypesInputFields(): FormArray {
    return this.contentTypeForm.get('contentTypesInputFields') as FormArray;
  }

  public setContentTypes(ctArr: ContentType[]) {
    const contentTypeFGs = ctArr.map(x => this.fb.group(x));
    const contentTypeFormArray = this.fb.array(contentTypeFGs);
    this.contentTypeForm.setControl('contentTypesInputFields', contentTypeFormArray);
  }

  public onSubmit(event: Event) {
    event.preventDefault();

    this.saveData();
  }

  public addContentTypeInputFields(): void {
    this.contentTypesInputFields.push(this.fb.group(new ContentType('', '', '', '')));
  }

  public removeContentTypeInputFields(test: FormGroup): void {
    const index = this.contentTypeInputFieldsArray.indexOf(test.value['name']);
    if (index > -1) {
      this.contentTypeInputFieldsArray.splice(index, 1);
    }
  }

  public saveData() {
    const ct: ContentType[] = this.prepareSaveContentType();
    const json = JSON.stringify(ct);
    this.dataService.saveData('ContentTypes', json);
    this.contentTypeInputFieldsArray = ct;
    this.contentTypeInputFieldsArrayOnLoad = ct;
    this.rebuildForm();
  }

  public prepareSaveContentType(): ContentType[] {
    const formModel = this.contentTypeForm.value;

    // deep copy of form model input fields
    const inputFieldsDeepCopy: ContentType[] = formModel.contentTypesInputFields.map(
      // nog ke zien of "javascript literal object" goed is
      (ct: ContentType) => Object.assign({}, ct)
    );

    // return new contenttype array object containing a combination of original values
    // and deep copies of changed form model values
    const saveCT: ContentType[] = inputFieldsDeepCopy;

    return saveCT;
  }

  public revertData() {
    /*this.contentTypeInputFieldsArray = this.contentTypeInputFieldsArrayOnLoad.slice();
    const tt = this.contentTypeInputFieldsArray;*/
    this.rebuildForm();
  }

}  

我还希望实现的是当我点击&#34;保存&#34;按钮,它将数据保存到服务(只是在地图中设置键/值)。当我离开这个组件时(例如导航到查看&#34; SiteColumns&#34;)然后当我回来时,我希望组件检查服务以查看服务/地图内是否有&#39;使用键&#39; ContentTypes的记录,如果是这样,请动态填写字段数量,以便显示用户保存的内容而不是空的&#34;内容类型&#34;再次。

此外,似乎没有正确建模将我的内容类型绑定到&#34; * ngFor&#34;它似乎。

你们中任何人都可以看到问题(或者可能是多个问题)吗?

0 个答案:

没有答案