首页 > 解决方案 > 如何使用 Angular Material Reactive Form 和 Restful API 更新数据库

问题描述

让我以著名的书籍示例来解释我的问题。我在 BookService.ts 中有一个基于 Book Model 的角度材料反应形式。当我更改此表单中的某些字段并将其提交到我的后端以使用 Angular HttpClient PUT 方法更新相应的记录时,它没有更新我的数据库并返回错误。当我调试它时,它显示 ID 未定义,当我console.log(BookForm.value)得到这个输出时:{$key: 1234, Title: "Book Title1", Topic: "Topic1"}无需说我的 Angular HttpClient PUT Restful API 需要该 ID 才能更新我的数据库表中的特定记录。Bellow 是我的简化模拟代码来解释它。

BookModel.ts File, My Model

export interface Book{
    ID: number;
    Title: string;
    Topic: string;
}
BookService.ts File, My Service

BookForm: FormGroup = new FormGroup({
    $key: new FormControl(null),
    Title: new FormControl('', Validators.required),
    Topic: new FormControl('', Validators.required),
});


UpdateBook(bookObj: Book): Observable<Book>
{
return this.http.put<Book>(`...api/book/${bookObj.ID}`, bookObj,{
    headers: new HttpHeaders({
    'Content-Type: 'application/json'
   })
 })
}

Note: This Throw Error, ID Undefined
Book-form.component.html File

<form [formGroup] = "BookService.BookForm" class="FormCls">
 <mat-grid-list rowHeight="200px">
  <mat-grid-tile>
      <div class="form-controles-container">
        <input type="hidden" formControlName="$key" />
        <mat-form-field>
          <input formControlName="Title" matInput placeholder="Title*" />
          <mat-error>Title Needed</mat-error>
        </mat-form-field>
        <mat-form-field>
          <input formControlName="Topic" matInput placeholder="Topic*" />
          <mat-error>Topic Needed</mat-error>
        </mat-form-field>

        <div class="button-row">
          <button mat-raised-button color="primary" type="submit" (click)="onSubmit()">Submit</button>
        </div>

      </div>
  </mat-grid-tile>
 </mat-grid-list>
</form>
Book-form.component.ts File

onSubmit(): void 
{
    BookService.UpdateBook(BookService.BookForm.value).subscribe(
     b => alert(`Book Updated Successfully`),
     err => alert(`Exception While Updating: ${err}`) 
 );
}

当然,我知道我需要一些如何将我的表单值转换为我的 Book 模型的方法,并确保在我将它传递给我的 http put 服务之前,我有那个 ID。但我不知道该怎么做,我在 Angular 和 Typescript 世界中都是新手,我正在学习。我喜欢在问之前阅读,所以浏览了很多文章,但没有一个对我有用。例如,我在 stackoverfelow 上尝试了下面的文章,但对我不起作用 反应式表单正确地将表单值转换为模型对象

我真的很感谢您的专业人士,并感谢您的时间和帮助。

标签: asp.netangulartypescriptasp.net-coreangular-material

解决方案


当您调用 anyAbstractControl.value方法时,您将获得一个对象,其中包含prop: value表单中每个输入的对。如您所见,您将得到一个无 ID 的对象,可能是因为表单没有 'ID' 属性,也可能是因为值为 null(当您将对象转换为 JSON 时,所有具有 null 值的属性被删除)。

如果您知道 HTML 中的 id,则可以在函数中传递它 <button mat-raised-button color="primary" type="submit" (click)="onSubmit(sth.id)">

如果不是这种情况(我认为不是),您可以在使用.patchValue({ id: idInfo })任何 AbstractControl 具有的方法调用您的服务之前添加 ID(在这种情况下,您不需要添加隐藏输入,除非您添加它另一个原因)。

在调用服务之前做一个补丁,它应该可以工作。

我不确定这些信息是否足以帮助您,请随时提出任何问题。

编辑(添加代码示例):

onSubmit(): void 
{
    // the lines I added
    const bf = BookService.BookForm;
    bf.patchValue({ ID: 'anyIdYouLike' });

    // what stays the same (except the bf.value shortened version)
    BookService.UpdateBook(bf.value).subscribe(
       b => alert(`Book Updated Successfully`),
       err => alert(`Exception While Updating: ${err}`) 
 );
}

推荐阅读