所以这是一个Angular 5应用程序。对于这个问题,我查看了Angular.io基本文档/ exmaple应用程序(可以在这里找到:https://angular.io/guide/reactive-forms),但我似乎无法在我的工作(正确)上工作结束:(。我也想说我对Angular来说是非常新的。
所以我打破这篇文章,解释我想要的东西,尝试用打印屏幕(以及我的评论)显示它,然后显示我的组件和代码的代码。服务,以便您可以全面了解我想要什么,我有什么,可能是什么错。此外,不要担心到处都是可怕的布局,现在不重要(它只需要工作)。
所以它是一个从Sharepoint获取/创建内容的应用程序,但是如果你不了解Sharepoint的任何内容,那么理解这个问题并不是一个问题。
用户将登录特定的Sharepoint租户/站点,然后被重定向到我的第一个视图,我希望用户能够动态地在表单中制作内容类型。我的意思是理想情况下,显示一个空的,他可以添加"内容类型"随心所欲。内容类型可以被视为"类"在正常编程中。
首先,这会产生一些错误:
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)
当我点击任何内容或在任何地方键入任何字符/字符串时,似乎"循环"通过我的控件(它似乎无法找到),它最终看起来像这样(就像它应该):
它循环的错误与上面相同,只是这次也适用于' Group'和' ContentTypeInherit'。这张图片与之前的图片有一些区别:现在它说"内容类型#1"还有我的"继承自内容类型:"标签&选择该节目(并填写选择)。
我现在要点击按钮添加一个新的"测试行",第一张图片是点击按钮后立即显示的图片,第二张图片显示了在输入一对夫妇后的样子事情(所以它可以再次循环错误):
当我点击我的"删除"按钮它应该删除"内容类型"它被点击的字段,所以如果我点击"删除"内容类型#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;它似乎。
你们中任何人都可以看到问题(或者可能是多个问题)吗?