首页 > 解决方案 > Reactive Forms type mismatch with data

问题描述

I find that a lot of times there are small differences between the structure of the data I get/post to my web services and the structure of the data needed by my form. What is the best way to handle a mismatch when using reactive forms. Can I have some sort of getter/setter on an individual property in a form group? What would I use for the formGroup name?

Now I am writing two transformation functions - one from my data Model to my formModel that I run onInit before I can patch the formGroup and one from my formModel to my dataModel that I run on save before I can post my data back

For example my webservices get/post this structure has seconds but the UI req is for days.

interface Request
{
   name:string, 
   description:string, 
   processBy: number //the number of seconds
}

but the UI is just going to to ask for a number of days

interface formModel 
{
   name:string, 
   description:string, 
   processByDays: number 
}
<input type="number" formControlName="processByDays" /> 

I had similar problems with using a custom list control that wanted an array but my data was a scalar so I had a bunch of clunky code just to wrap/unwrap a scalar value.

标签: angularangular-reactive-formstype-mismatch

解决方案


这个问题没有通用的解决方案。但是,您不应该在表单中或表单周围处理这种转换。处理保存数据的服务中的转换。您需要为每个字段执行此操作,因为它是特定于您的业务逻辑的转换。

@Injectable() export class DataService {
  save(data: FormModel): Observable<void> {
    const {processByDays, ...saveAsIs} = data;
    const saveModel: Request = {
      ...saveAsIs,
      processBy: processByDays * 24 * 60 ** 2
    };

    return this.http.post(myURL, saveModel);
  }
}

您可以使用Moment.js来提高可读性。

import moment from 'moment';

const {processByDays, ...saveAsIs} = data;

const saveModel: Request = {
  ...saveAsIs,
  processBy: moment.duration(processByDays, 'days').asSeconds()
};

推荐阅读