无法在 Angular 响应式表单中设置表单加载的默认值
Not able to set default values on Form Load in Angular Reactive Forms
基本上我需要通过传递id来执行http请求。收到回复后,我需要将值分配给表单字段。
我试过使用 setValue 和 patchValue。但是没用
sp服务
itemData = new ItemData()
getItembyID(itemID) {
return this.http.get<Object>(this.baseUrl +"items("+itemID+")")
.pipe(map ((response : Response) => {
const data = response['d']
return data
})
).subscribe((data : Response) => {
this.setItemData(data)
})
}
setItemData(data) {
this.itemData.requestno = data.Request_x0020_Number
this.itemData.requestid = data.Request_x0020_ID
编辑-form.component.ts
constructor(private spService : SharepointService,
private formBuilder : FormBuilder)
ngOnInit() {
this.route.params.subscribe((param : Params)=> {
const id = param['ID']
this.spService.getItemByID(ID)
})
this.itemData = this.sharepointService.itemData
// In console, I can see the details of the itemData but not able to set to the formcontrols.
this.editForm = this.formBuilder.group({
RequestNo : [''],
RequestId : ['']
})
this.editForm.patchValue({
RequestNo : this.itemData.requestno,
RequestId : this.itemData.requestid
})
} // End of OnInit
编辑-form.component.html
<form [formGroup]= "editForm">
<label> DefaultRequestNo </label>
<input type="text" formControlName="RequestNo">
<label> DefaultRequestID </label>
<input type="text" formControlName="RequestId">
</form>
这里的问题是您服务中的 itemData 无法同步使用,但您正在访问它,就好像它是同步的一样。您应该在您的服务中设置一个您的组件可以订阅的主题:
修改后的 SP 服务:
itemData = new ItemData();
private itemDataSource = new ReplaySubject<ItemData>(1);
itemData$ = this.itemDataSource.asObservable();
getItembyID(itemID) {
return this.http.get<Object>(this.baseUrl +"items("+itemID+")")
.pipe(map ((response : Response) => {
const data = response['d']
return data
})
).subscribe((data : Response) => {
this.setItemData(data)
})
}
setItemData(data) {
this.itemData.requestno = data.Request_x0020_Number;
this.itemData.requestid = data.Request_x0020_ID;
this.itemDataSource.next(this.itemData);
}
那么您可以在您的组件中订阅:
// just do this once
this.editForm = this.formBuilder.group({
RequestNo : [''],
RequestId : ['']
})
this.sharepointService.itemData$.subscribe(itemData => {
this.itemData = itemData;
this.editForm.setVale({
RequestNo : this.itemData.requestno,
RequestId : this.itemData.requestid
});
});
您的日志对您而言 "lying" 的原因;在您的服务中,您设置了一个初始对象值,然后只改变该对象。当您在控制台中记录一个对象时,它不会向您显示 'point in time' 值,它会向您显示对该对象的引用以及该引用中的值,因此即使数据在以下情况下实际上不可用您尝试设置表单值,当它最终被设置时,它仍然会出现在您的日志中。
这是为什么您应该在 Javascript 中避免对象突变的众多原因之一,而是每次更改时都实例化一个新对象,例如:
setItemData(data) {
this.itemData = Object.assign({}, this.itemData, {
requestno: data.Request_x0020_Number,
requestid: data.Request_x0020_ID
});
this.itemDataSource.next(this.itemData);
}
此方法将确保您不会改变新对象,而是每次都创建一个新对象。这种特殊的方法可能不适合你的用例,但原理是一样的,不要变异。
您似乎在尝试手动设置默认值,而不是让 FormBuilder 管理它们。您应该尝试将上面的代码修改为:
this.editForm = this.formBuilder.group({
RequestNo : [data.Request_x0020_Number],
RequestId : [data.Request_x0020_ID]
})
应该可以。
要在编辑点击时设置默认值,可以使用@rxweb/reactive-form-validators中的FormBuilderConfiguration
您可以设置来自 defaultValue
属性 中编辑 api 调用的值,如下所示:
setItemData()
{
let user = new User();
var formBuilderConfig = new FormBuilderConfiguration();
formBuilderConfig.propsConfig = {'RequestNo':{defaultValue:"abc1"},"RequestId":{defaultValue:1}}
this.editForm = <RxFormGroup>this.formBuilder.formGroup(user,formBuilderConfig);
}
您需要在应用组件中导入RxReactiveFormsModule
这里是完整的组件代码
import { Component, OnInit } from '@angular/core';
import { FormGroup,FormArray } from "@angular/forms"
import { RxFormBuilder,RxFormGroup,FormBuilderConfiguration } from '@rxweb/reactive-form-validators';
import { User, } from './user.model';
@Component({
selector: 'app-user',
templateUrl: './patch-complete.component.html'
})
export class UserComponent implements OnInit {
editForm: RxFormGroup
constructor(
private formBuilder: RxFormBuilder ) { }
ngOnInit() {
let user = new User();
this.editForm = <RxFormGroup>this.formBuilder.formGroup(user);
// this.itemData = this.sharepointService.itemData
// In console, I can see the details of the itemData but not able to set to the formcontrols.
}
setItemData()
{
let user = new User();
var formBuilderConfig = new FormBuilderConfiguration();
formBuilderConfig.propsConfig = {'RequestNo':{defaultValue:"abc1"},"RequestId":{defaultValue:1}}
this.editForm = <RxFormGroup>this.formBuilder.formGroup(user,formBuilderConfig);
}
}
<div>
<form [formGroup]= "editForm">
<label> DefaultRequestNo </label>
<input type="text" formControlName="RequestNo">
<br/>
<label> DefaultRequestID </label>
<input type="text" formControlName="RequestId">
<br/>
<button (click)="setItemData()">SetItemData</button>
</form>
</div>
基本上我需要通过传递id来执行http请求。收到回复后,我需要将值分配给表单字段。
我试过使用 setValue 和 patchValue。但是没用
sp服务
itemData = new ItemData()
getItembyID(itemID) {
return this.http.get<Object>(this.baseUrl +"items("+itemID+")")
.pipe(map ((response : Response) => {
const data = response['d']
return data
})
).subscribe((data : Response) => {
this.setItemData(data)
})
}
setItemData(data) {
this.itemData.requestno = data.Request_x0020_Number
this.itemData.requestid = data.Request_x0020_ID
编辑-form.component.ts
constructor(private spService : SharepointService,
private formBuilder : FormBuilder)
ngOnInit() {
this.route.params.subscribe((param : Params)=> {
const id = param['ID']
this.spService.getItemByID(ID)
})
this.itemData = this.sharepointService.itemData
// In console, I can see the details of the itemData but not able to set to the formcontrols.
this.editForm = this.formBuilder.group({
RequestNo : [''],
RequestId : ['']
})
this.editForm.patchValue({
RequestNo : this.itemData.requestno,
RequestId : this.itemData.requestid
})
} // End of OnInit
编辑-form.component.html
<form [formGroup]= "editForm">
<label> DefaultRequestNo </label>
<input type="text" formControlName="RequestNo">
<label> DefaultRequestID </label>
<input type="text" formControlName="RequestId">
</form>
这里的问题是您服务中的 itemData 无法同步使用,但您正在访问它,就好像它是同步的一样。您应该在您的服务中设置一个您的组件可以订阅的主题:
修改后的 SP 服务:
itemData = new ItemData();
private itemDataSource = new ReplaySubject<ItemData>(1);
itemData$ = this.itemDataSource.asObservable();
getItembyID(itemID) {
return this.http.get<Object>(this.baseUrl +"items("+itemID+")")
.pipe(map ((response : Response) => {
const data = response['d']
return data
})
).subscribe((data : Response) => {
this.setItemData(data)
})
}
setItemData(data) {
this.itemData.requestno = data.Request_x0020_Number;
this.itemData.requestid = data.Request_x0020_ID;
this.itemDataSource.next(this.itemData);
}
那么您可以在您的组件中订阅:
// just do this once
this.editForm = this.formBuilder.group({
RequestNo : [''],
RequestId : ['']
})
this.sharepointService.itemData$.subscribe(itemData => {
this.itemData = itemData;
this.editForm.setVale({
RequestNo : this.itemData.requestno,
RequestId : this.itemData.requestid
});
});
您的日志对您而言 "lying" 的原因;在您的服务中,您设置了一个初始对象值,然后只改变该对象。当您在控制台中记录一个对象时,它不会向您显示 'point in time' 值,它会向您显示对该对象的引用以及该引用中的值,因此即使数据在以下情况下实际上不可用您尝试设置表单值,当它最终被设置时,它仍然会出现在您的日志中。
这是为什么您应该在 Javascript 中避免对象突变的众多原因之一,而是每次更改时都实例化一个新对象,例如:
setItemData(data) {
this.itemData = Object.assign({}, this.itemData, {
requestno: data.Request_x0020_Number,
requestid: data.Request_x0020_ID
});
this.itemDataSource.next(this.itemData);
}
此方法将确保您不会改变新对象,而是每次都创建一个新对象。这种特殊的方法可能不适合你的用例,但原理是一样的,不要变异。
您似乎在尝试手动设置默认值,而不是让 FormBuilder 管理它们。您应该尝试将上面的代码修改为:
this.editForm = this.formBuilder.group({
RequestNo : [data.Request_x0020_Number],
RequestId : [data.Request_x0020_ID]
})
应该可以。
要在编辑点击时设置默认值,可以使用@rxweb/reactive-form-validators中的FormBuilderConfiguration
您可以设置来自 defaultValue
属性 中编辑 api 调用的值,如下所示:
setItemData()
{
let user = new User();
var formBuilderConfig = new FormBuilderConfiguration();
formBuilderConfig.propsConfig = {'RequestNo':{defaultValue:"abc1"},"RequestId":{defaultValue:1}}
this.editForm = <RxFormGroup>this.formBuilder.formGroup(user,formBuilderConfig);
}
您需要在应用组件中导入RxReactiveFormsModule
这里是完整的组件代码
import { Component, OnInit } from '@angular/core';
import { FormGroup,FormArray } from "@angular/forms"
import { RxFormBuilder,RxFormGroup,FormBuilderConfiguration } from '@rxweb/reactive-form-validators';
import { User, } from './user.model';
@Component({
selector: 'app-user',
templateUrl: './patch-complete.component.html'
})
export class UserComponent implements OnInit {
editForm: RxFormGroup
constructor(
private formBuilder: RxFormBuilder ) { }
ngOnInit() {
let user = new User();
this.editForm = <RxFormGroup>this.formBuilder.formGroup(user);
// this.itemData = this.sharepointService.itemData
// In console, I can see the details of the itemData but not able to set to the formcontrols.
}
setItemData()
{
let user = new User();
var formBuilderConfig = new FormBuilderConfiguration();
formBuilderConfig.propsConfig = {'RequestNo':{defaultValue:"abc1"},"RequestId":{defaultValue:1}}
this.editForm = <RxFormGroup>this.formBuilder.formGroup(user,formBuilderConfig);
}
}
<div>
<form [formGroup]= "editForm">
<label> DefaultRequestNo </label>
<input type="text" formControlName="RequestNo">
<br/>
<label> DefaultRequestID </label>
<input type="text" formControlName="RequestId">
<br/>
<button (click)="setItemData()">SetItemData</button>
</form>
</div>