修补 angular 形式的值
Patch the values in angular form
我正在使用 angular 6 制作应用程序,我正在使用 angular 动态表单。
至于创建表单并提交我已经完成了所有事情,您可以看到工作 stackblitz、https://stackblitz.com/edit/angular-x4a5b6-hne6fg
仅供参考:此表单包含子元素,这些子元素将在单击“添加”按钮时打开并追加,并在单击“删除”按钮时逐个删除。
我需要的是,我只需要在编辑每一行的过程中分别通过服务将值修补到每个输入..
假设我调用 get 服务 作为,
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)
})
我正在尝试将值修补为您可以在 dynamic-form.ts in stacblitz,
中看到的形式
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
具有 值 作为新模板和 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
会被绑定..
请帮助实现数据到表单元素的修补...
使用patchValue
设置数据形成
this.dynamicFormService.getRest(url,token).subscribe(res => {
this.form.patchValue({
template_desc: res.data.template_desc,
template_name: res.data.template_name,
});
}
在https://stackblitz.com/edit/angular-x4a5b6-xcychx?file=src%2Fapp%2Fdynamic-form.component.html中,我输入为"path the values".
唯一需要考虑的是,您需要像数组一样将元素添加到表单中。
//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 有问题(关于 as convert propertyOrigin to series of checkBox 的问题,等我一段时间 -I'稍后我会更新这个答案-)
已更新
见 stackblitz updated
创建一个新的问题类型以创建一个复选框列表
复选框有问题。在 Angular 中,一个复选框只能有两个值 "true" 或 "false"。直到我知道,属性值没有影响。
所以,我们不能做出类似
的东西
<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}
好吧,一个工作是制作一个新的问题类型"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"]。我们必须使用 map
更新
看一下问题控制服务的 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))
}
}
我正在使用 angular 6 制作应用程序,我正在使用 angular 动态表单。
至于创建表单并提交我已经完成了所有事情,您可以看到工作 stackblitz、https://stackblitz.com/edit/angular-x4a5b6-hne6fg
仅供参考:此表单包含子元素,这些子元素将在单击“添加”按钮时打开并追加,并在单击“删除”按钮时逐个删除。
我需要的是,我只需要在编辑每一行的过程中分别通过服务将值修补到每个输入..
假设我调用 get 服务 作为,
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)
})
我正在尝试将值修补为您可以在 dynamic-form.ts in stacblitz,
中看到的形式 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
具有 值 作为新模板和 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
会被绑定..
请帮助实现数据到表单元素的修补...
使用patchValue
设置数据形成
this.dynamicFormService.getRest(url,token).subscribe(res => {
this.form.patchValue({
template_desc: res.data.template_desc,
template_name: res.data.template_name,
});
}
在https://stackblitz.com/edit/angular-x4a5b6-xcychx?file=src%2Fapp%2Fdynamic-form.component.html中,我输入为"path the values".
唯一需要考虑的是,您需要像数组一样将元素添加到表单中。
//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 有问题(关于 as convert propertyOrigin to series of checkBox 的问题,等我一段时间 -I'稍后我会更新这个答案-)
已更新 见 stackblitz updated 创建一个新的问题类型以创建一个复选框列表 复选框有问题。在 Angular 中,一个复选框只能有两个值 "true" 或 "false"。直到我知道,属性值没有影响。
所以,我们不能做出类似
的东西<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}
好吧,一个工作是制作一个新的问题类型"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"]。我们必须使用 map
更新 看一下问题控制服务的 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))
}
}