Reactive Forms正确地将Form Value转换为Model Object

Kis*_*ash 17 typescript angular

在创建模型驱动模板Reactive表单时,我从Form Value创建模型对象时.然后模型对象失去其TYPE.

对于一个简单的例子:

模特班书:

export class Book {
  public name: string;
  public isbn: string;
}
Run Code Online (Sandbox Code Playgroud)

零件:

@Component({
  selector: 'app-book',
  templateUrl: './book.component.html',
  styleUrls: ['./book.component.css']
})
export class BookComponent implements OnInit {

  bookFormGroup: FormGroup;
  private newBook: Book = new Book();

  constructor(private fb: FormBuilder) {
    this.bookFormGroup = this.fb.group({
      name: new FormControl(''),
      isbn: new FormControl('')
    });
  }

  ngOnInit() {
  }

  addBook() {
    console.log('submit');
    this.newBook = <Book> this.bookFormGroup.value;
    console.log(this.newBook instanceof Book);
    console.log(this.newBook);
  }

}
Run Code Online (Sandbox Code Playgroud)

HTML:

<form [formGroup]="bookFormGroup" (ngSubmit)="addBook()">
    <input type="text" formControlName="name" >
    <input type="text" formControlName="isbn" >

    <input type="submit" value="Submit">
</form>
Run Code Online (Sandbox Code Playgroud)

在上面的例子中,填充newBook实例后它转换为正常Object

即,之后 this.newBook = <Book> this.bookFormGroup.value;

this.newBook instanceof Book 正变成 FALSE

我该如何防止这种情况?或者有更好的方法来实现这一目标吗?

注意:我试过JSON.parse()但它仍然相同.

Tos*_*nev 31

此构造函数将适用于任何类型,并将分配任何匹配的字段.

export class Book {
  public constructor(init?: Partial<Book>) {
        Object.assign(this, init);
    }
}
Run Code Online (Sandbox Code Playgroud)

所以你将能够做到这一点:

this.newBook = new Book(this.bookFormGroup.value);
Run Code Online (Sandbox Code Playgroud)

如果Book课程将来会有任何变化并且变得更大,这将为您提供大量工作.

  • 只需在构造函数中调用空的super()即可.父字段也将适用. (2认同)

Hus*_*dan 11

我使用传播运算符:

this.newBook = {...this.newBook,...this.bookFormGroup.value}
Run Code Online (Sandbox Code Playgroud)

  • 您将发布到服务器的表单值不应包含函数。@HawklmCG (3认同)

小智 6

  1. 您应该有一个接口和一个类,并且该类应该实现该接口。

  2. 使用空构造函数创建一本空书。

    export class Book implements IBook {
      constructor(public name = '', public isbn = '') {}
    }
    
    Run Code Online (Sandbox Code Playgroud)
  3. 创建真正的模型驱动表单。

    this.bookFormGroup = this.fb.group(new Book());
    
    Run Code Online (Sandbox Code Playgroud)
  4. 正确输入您的表格

    this.newBook: IBook = this.bookFormGroup.value;
    
    Run Code Online (Sandbox Code Playgroud)

  • 当我们向 bookFormGroup 传递一个 new Book() 时,如何向 bookFormGroup 添加验证? (2认同)

kat*_*aer 6

let formData = this.formGroup.value as DataModel;
Run Code Online (Sandbox Code Playgroud)


Rag*_*hav 5

假设您的模型是这样的:

export class Content {
    ID: number;
    Title: string;
    Summary: string;
}
Run Code Online (Sandbox Code Playgroud)

您的组件将如下所示:

export class ContentComponent implements OnInit {


  content: Content;
  contentForm: FormGroup;

  ngOnInit() {


    this.contentForm = this.formBuilder.group({
      Title: ['', Validators.required],
      Summary: ['', Validators.required]
    });.....
Run Code Online (Sandbox Code Playgroud)

调用保存按钮时,您可以合并表单构建器对象和您拥有的 dto:

onContentFormSubmit() {

// stop here if form is invalid
if (this.contentForm.invalid) {
  return;
}

this.content = Object.assign(this.content, this.contentForm.value);
Run Code Online (Sandbox Code Playgroud)

}

this.content 将具有您从 onInit 获得的预定义值和来自 from 组的值。