如果成员在JSON字符串中缺失,则将其解析为未定义值而不是默认值

htrmnn0y  于 2022-12-05  发布在  其他
关注(0)|答案(2)|浏览(90)

将整个模型从服务器端传输到客户端,特别是在加载列表的时候,开销非常大。解决方案是忽略空值、null或默认值,这些值可以在客户端重新填充。考虑一个Customer模型,如下所示:

export class Customer {
    customerId: number = 0;
    ncode: string = 'some default text';
    name: string = '';
    age: int = 20;
    isActive: boolean = false;
    birthday: Date | null = null;

    // And much more fields ...
}

我们在服务器端有相同的模型,服务器在序列化时会忽略null和默认字段。例如,这是一个从服务器发送的客户:

"{'customerId':1234}"

所发生的是,由angular http get创建的对象是一个只有customerId字段的Customer!所有其他字段都是未定义的。有没有解决方案来全局修复它,而不使用第三方库来强制angular使用默认值来值丢失的字段?
更新:以下是请求代码:

export class CustomerComponent implements OnInit {
  constructor(private http: HttpClient) { }

  ngOnInit(): void {
    this.http.get<Customer>('/api/getCustomer').subscribe((response) => {
      console.log(response); // {'customerId':12345}
    });
  }
}

更新2:因为我认为可能有一个全局解决方案,所以我做了一个简单的例子,但是我们有一个泛型函数来处理所有的api请求,它是泛型的,返回<T>(<any>response)

public request<T>(api: string, method: string = 'GET', formData: any): Observable<T>{
    return new Observable((observer: Observer<T>) => {
        header = new HttpHeaders({/*...*/});
        this.http.request<T>(new HttpRequest(method, api, JSON.stringify(formData), {headers: header}))
            .subscribe({next: (response) => {
                observer.next(<T>(<any>response)); // <= This line must be changed I think
            }});
    }
}
3hvapo4f

3hvapo4f1#

当您从后端接收数据时,您可以使用以下技巧:
1.示例化所需类的新对象:它将自动包含您的默认值。
1.使用spread运算符将新创建的对象与传入数据合并。

ngOnInit(): void {      
    this.http.get<Customer>('/api/getCustomer').pipe(
        // Instantiate an object with default-values
        // and merge it with the retrieved partial-object:
        map(res =>({ ...new Customer(), ...res } as Customer))
    )
    .subscribe((response) => { console.log(response); });
}
q3qa4bjr

q3qa4bjr2#

已说明

使用Customer类作为http请求的类型不会影响运行时代码。Http resonse不会自动创建Customer类的新示例并为其赋值。typescript中的类型仅用于开发目的(编译器时间),不会影响运行时代码结果。查看w3school简介。
TypeScript使用编译时类型检查。这意味着它在运行代码之前检查指定的类型是否匹配,而不是在运行代码时。

解决方案

若要取得具有预设值的Customer,您可以建立Customer的新执行严修,其具有您已定义的静态预设值,并仅指派已设定的http resonse值。例如:

this.http.get<Customer>('/api/getCustomer').subscribe((response) => {
      const customer = {...new Customer(), ...response}; // use spread operator to merge the two objects (defaults, response values)
      console.log(customer); // response will be a Customer instance 
    });

使用spread算子的灵感来自kellermat解决方案。

相关问题