Реактивные формы правильно преобразуют значение формы в объект модели

При создании модифицированных шаблонов шаблонов, когда я создаю объект модели из значения формы. Тогда объект модели теряет свой ТИП.

Для простого примера:

Модельная книга:

export class Book {
  public name: string;
  public isbn: string;
}

Составная часть:

@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);
  }

}

HTML:

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

    <input type="submit" value="Submit">
</form>

В приведенном выше примере после заполнения экземпляра newBook его преобразование в обычный Object

т.е. после this.newBook = <Book> this.bookFormGroup.value;

this.newBook instanceof Book становится FALSE

Как я могу это предотвратить? Или есть лучший способ добиться этого?

Примечание. Я попытался использовать JSON.parse() но он все тот же.

Ответ 1

Этот конструктор будет работать с любым типом и будет присваивать любые соответствующие файлы.

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

Таким образом, вы сможете это сделать:

this.newBook = new Book(this.bookFormGroup.value);

Это сэкономит вам много работы, если класс Book будет иметь какие-либо изменения в будущем и станет больше.

Ответ 2

  1. У вас должен быть интерфейс и класс, а класс должен реализовывать интерфейс.

  2. Создайте пустую книгу с пустым конструктором.

    export class Book implements IBook {
      constructor(public name = '', public isbn = '') {}
    }
    
  3. Создайте реальную модельную форму.

    this.bookFormGroup = this.fb.group(new Book());
    
  4. Правильно введите свою форму

    this.newBook: IBook = this.bookFormGroup.value;
    

Ответ 3

Измените определение класса на

export class Book {
  constructor(public name: string, public isbn: string) {}
}

Измените свой метод addBook на

addBook() {
  const { name, isbn } = this.bookFormGroup.value;
  this.newBook = new Book(name, isbn);
  console.log(this.newBook instanceof Book);
  console.log(this.newBook);
}

Ответ 4

вы можете попробовать это в своем addBook():

 let formData = Object.assign({});
 formData = Object.assign(formData, this.bookFormGroup.value);
 this.newBook = new Book(formData.name ,formData.isbn );
 console.log(this.newBook instanceof Book);

Ответ 5

У меня была эта проблема, и я создал форму GroupGroup непосредственно для моделирования, решил проблему. В вашем коде:

  this.bookFormGroup = this.fb.group(Book);

Книга - это название класса вашей модели.

Ответ 6

Я использую оператор распространения:

this.newBook = {...this.newBook,...this.bookFormGroup.value}