以角度形式修补值
Posted
技术标签:
【中文标题】以角度形式修补值【英文标题】:Patch the values in angular form 【发布时间】:2019-04-12 17:02:55 【问题描述】:我正在使用 angular 6 制作应用程序,我使用的是 angular 动态形式。
在创建表单并提交时,我已经完成了所有工作,您可以看到正在运行的 stackblitz,https://stackblitz.com/edit/angular-x4a5b6-hne6fg
仅供参考:此表单有子元素,它们将被打开并在单击添加按钮时附加,并在单击删除按钮时逐个删除..
我需要的是,我只需要在编辑每一行期间分别通过服务将值修补到每个输入..
假设我将 get service 称为,
this.dynamicFormService.getRest(url,token).subscribe(res =>
this.form.value = res.data; //Tried this line but got error (Cannot assign to 'value' because it is a constant or a read-only property)
)
我正在尝试将值修补到您可以在 stacblitz 的 dynamic-form.ts 中看到的表单中,
ngOnInit()
this.form = this.qcs.toFormGroup(this.questions);
如果我将表单控制台设置为console.log(this.form.value)
,它会给出结果,
template_desc: ""
template_name: ""
template_properties: Array(0)
length: 0
__proto__: Array(0)
而console.log(res.data)
在获取服务结果中给出,
data:
template_obj_id: "123"
template_desc: "New template description"
template_name: "New Template"
template_properties: Array(1)
0:
property_name: "Property name"
property_origin: ["VBM"]
property_required: true
property_type: "Property type"
我只需要将来自 res.data 的数据绑定到所有表单输入中。
这些是我需要分别修补到所有输入的值,例如 template_name
具有 value 作为新模板,template_desc
作为 New template description
等。
对于template_properties
值还有一个重要的事情,即数组将在创建过程中单击添加按钮打开,但在编辑过程中它应该自动打开,template_properties
中存在行数..
虽然问题的解释有点大,但我需要的是单一的..我需要将来自服务 (res.data) 的数据分别修补到每个表单元素和包括template_properties
在内的所有表单元素都需要可见,用户可以在其中编辑和提交表单。
res.data的截图,
尝试了以下答案,
this.form.patchValue(
template_desc: res.data.template_desc,
template_name: res.data.template_name,
);
但是如果我给template_properties: res.data.template_properties
,模板属性不会被绑定,但其他两个template name and desc
会被绑定..
请帮助实现将数据修补到表单元素...
【问题讨论】:
【参考方案1】:在https://stackblitz.com/edit/angular-x4a5b6-xcychx?file=src%2Fapp%2Fdynamic-form.component.html 中,我将其作为“路径值”。
唯一需要考虑的是,您需要像数组一样将元素添加到表单中。
//This function serve to add to the array the elments of the arrays
//Is the same that we use when add a new line to the Array Form
addControls(control: string)
let question: any = this.questions.find(q => q.key == control);
let children = question ? question.children : null;
if (children)
(this.form.get(control) as FormArray).push(this.qcs.toFormGroup(children))
this.dynamicFormService.getRest(url,token).subscribe(res =>
//In res.data you have the data.
//In res.dat.template_properties you has the array
//Create the Form
this.form = this.qcs.toFormGroup(this.questions);
//Add so element at array as was necesary
for (let i=0;i<this.data.myArray.length;i++)
this.addControls('template_properties')
//Finally use patchValue
this.form.patchValue(res.data);
好吧,您的数据与 this.questions 不对应,并且您的 property_origin 有问题(关于将 propertyOrigin 转换为一系列复选框的问题,让我有时间 - 我稍后会更新这个答案 -)
更新 见stackblitz updated 创建新的问题类型以创建复选框列表 复选框有问题。在 Angular 中,一个复选框只能有两个值“真”或“假”。在我知道之前,属性值没有影响。
所以,我们不能做出类似的东西
<input type="checkbox" value="car" formControlName="checkName">
<input type="checkbox" value="dog" formControlName="checkName">
如果您检查了两个值,则在“checkName”中获取一个数组 ['car','dog']。
我们如何解决这个问题?我认为更好的主意是有一个 formGroup 像
<div formGroupName="checkName">
<input type="checkBox" formControlName="car">
<input type="checkBox" formControlName="dog">
</div>
所以,我们会得到一些类似的
checkName=car:true,dog:false
一项工作是创建一个新的 QuestionType "ListCheckBoxQuestion"
export class ListCheckBoxQuestion extends QuestionBase<string>
controlType = 'list-chekbox';
options: key: string, value: string[] = [];
constructor(options: = )
super(options);
this.options = options['options'] || [];
我们可以更改 dinamic-formquestion.component 后添加一个新开关。看到我们用question.key创建了一个formGroupName,在这个组里面我们用“options”创建了一个formControlName
<div [formGroupName]="question.key" *ngSwitchCase="'list-chekbox'" >
<ng-container *ngFor="let opt of question.options">
<input type="checkbox" [formControlName]="opt.key">
<label >opt.value</label>
</ng-container>
</div>
嗯,困难的部分是我们创建表单(question-control-service 的 toFormGroup 函数
toFormGroup(questions: QuestionBase<any>[])
let group: any = ;
questions.forEach(question =>
if (question.controlType=="array")
group[question.key]=new FormArray([]);
else if (question.controlType=="list-chekbox")
//We create a FromGroup using the options
let controls:any=;
for (let option of question.options)
controls[option.key]=new FormControl(false);
group[question.key]=new FormGroup(controls);
console.log("*",question);
else
...
);
return new FormGroup(group);
有一项工作就是将我们的 form.value 转换为数据,并将接收到的数据转换为 form.value。
当我们收到类似 ["car","dog"] 时,我们必须转换为 car:true,dog:true,当我们收到 car:true,dog:false 时,我们必须转换为 ["car "]。我们必须使用地图
更新 看一下question-control-service的toFormGroup函数。该函数是创建表单的函数。在上一个版本中,我们将这么多行添加到数组中作为值长度。如果没有指定值,则更改此函数以添加一条线
questions.forEach(question =>
if (question.controlType == "array")
group[question.key] = new FormArray([]);
if (question.value)
if (question.children)
//If question.children we must to give "value" to the children
//So the children has as value, the value given in dataArray
for (let value of question.value)
Object.keys(value).forEach(key =>
let qu = question.children.find(x => x.key == key)
if (qu)
qu.value = value[key];
qu.controlType = qu.elementType
)
group[question.key].push(this.toFormGroup(question.children))
//Add this lines to add one line to the array if no
//value is indicated
else
if (question.children)
question.children.forEach(qu =>
qu.controlType = qu.elementType
)
group[question.key].push(this.toFormGroup(question.children))
【讨论】:
查看我的更新答案。对不起,我赶时间,最后一部分(将数据转换为表格,将表格转换为数据未解决。希望您能做到或回答社区并有人可以帮助您) @ManiRaj,我更新了 stackblitz stackblitz.com/edit/…。有几处改动,所以我加了一个README.txt解释代码。我想你有不同的“json”,一个用于模型,一个用于数据,但我不确定你是否真的有一个独特的 json,数据和模型连接在一起。在这种情况下,必须更改代码 我想我终于明白了。在stackblitz.com/edit/… 中,您有一个由混合数据和模型的独特 jsonData 提供的动态表单供稿 @Mai 我更新了答案。关键是理解函数foFormGroup。有一个“奇怪的步骤”是给孩子们一个新的属性:“controlType”,需要显示控件 我的解释不好。您必须添加我指出的行,但不要删除函数的所有其余部分,请参阅我的 stackblitz.com/edit/angular-x4a5b6-28ysqg?file=src/app/…【参考方案2】:使用patchValue
设置表格数据
this.dynamicFormService.getRest(url,token).subscribe(res =>
this.form.patchValue(
template_desc: res.data.template_desc,
template_name: res.data.template_name,
);
【讨论】:
还有template_properties
会发生什么,因为它在单击添加按钮时打开,但在此修补期间,它需要自动打开并且需要填充template_properties
的相应数据。 以上是关于以角度形式修补值的主要内容,如果未能解决你的问题,请参考以下文章