【问题标题】:Not able to set default values on Form Load in Angular Reactive Forms无法在 Angular 反应式表单中设置表单加载的默认值
【发布时间】:2019-07-30 14:32:53
【问题描述】:

基本上我需要通过传递 id 来执行 http 请求。收到响应后,我需要将值分配给表单字段。

我尝试过使用 setValue 和 patchValue。但是没用

spService

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

edit-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

edit-form.component.html


<form [formGroup]= "editForm">
  <label> DefaultRequestNo </label>
  <input type="text" formControlName="RequestNo">

   <label> DefaultRequestID </label>
    <input type="text" formControlName="RequestId">

</form>

【问题讨论】:

  • 需要查看 SharePointService 以及 itemData 的填充方式/时间。如果它是同步可用的,那么您在此处所拥有的应该可以工作(尽管 IMO 有一种更简洁的方法来完成它)
  • 在 SharePoint 服务中,我有 itemData、getItemByID、setItemData 方法。我在顶部添加了 SharePoint 服务代码

标签: angular angular7 angular-reactive-forms


【解决方案1】:

这里的问题是您的服务中的 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
  });
});

您的日志对您“撒谎”的原因;在您的服务中,您设置一个初始对象值,然后只改变该对象。当您在控制台中记录一个对象时,它不会向您显示“时间点”值,它会向您显示对该对象的引用以及该引用的值,因此即使数据在您尝试设置表单值,但最终设置时它仍会出现在您的日志中。

这是您应该避免在 Javascript 中一般的对象突变,而是在每次更改类似内容时实例化一个新对象的众多原因之一:

  setItemData(data) {
    this.itemData = Object.assign({}, this.itemData, {
      requestno: data.Request_x0020_Number,
      requestid: data.Request_x0020_ID
    });

    this.itemDataSource.next(this.itemData);
  }

此方法将确保您不会改变新对象,而是每次都创建一个新对象。这个特定的方法可能不适合你的用例,但原理是一样的,不要变异。

【讨论】:

  • 谢谢@bryan60。它有效。在这里我可以使用行为主题或主题吗?
【解决方案2】:

要设置编辑点击的默认值,可以使用 @rxweb/reactive-form-validatorsFormBuilderConfiguration,您可以在其中设置值来自在 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>

这里是Working Example

【讨论】:

    【解决方案3】:

    似乎您正在尝试手动设置默认值,而不是让 FormBuilder 管理它们。您应该尝试将上面的代码修改为:

    this.editForm = this.formBuilder.group({
       RequestNo : [data.Request_x0020_Number],
       RequestId : [data.Request_x0020_ID]
    })
    

    应该可以。

    【讨论】:

      猜你喜欢
      • 2021-05-07
      • 2018-11-02
      • 1970-01-01
      • 1970-01-01
      • 2019-08-11
      • 2019-12-30
      • 2015-01-26
      • 2010-10-10
      相关资源
      最近更新 更多