Angular中订阅Observable后,Product类getter属性timeCreatedDisplay失效问题
问题分析与解决方案
嘿,我完全懂你碰到的这个坑!咱们来拆解一下问题根源,再给你几个靠谱的解决办法:
为什么会出现undefined?
当Angular的HttpClient从服务器拿到响应时,它只是把JSON数据转换成了普通的JavaScript对象,而不是你定义的Product类的实例。也就是说,你订阅后得到的product对象虽然有timeCreated这个属性,但压根没有timeCreatedDisplay这个getter方法——这就是为什么控制台里它显示undefined的原因。
解决方案一:手动创建Product类实例
你可以在订阅的时候,把服务器返回的原始对象转换成Product的实例。首先给Product类加个方便初始化的构造函数:
export class Product { timeCreated: number; // 用Partial来接受部分属性,方便快速初始化 constructor(data?: Partial<Product>) { Object.assign(this, data); } get timeCreatedDisplay() { const dateObject = new Date(this.timeCreated); return `${dateObject.getDate()}/${dateObject.getMonth() + 1}/${dateObject.getFullYear()}`; } }
然后在组件的订阅代码里,直接用原始数据创建实例:
this.productService.getProduct(this.productId).subscribe(rawProduct => { this.product = new Product(rawProduct); });
解决方案二:在服务层统一转换实例
如果不想在每个组件里都处理转换,可以把转换逻辑放到服务里,用map操作符把响应转换成Product实例:
getProduct(id: number): Observable<Product> { return this.http.get<Product>(`${this.baseURL}/${id}`).pipe( map(rawProduct => new Product(rawProduct)) ); }
这样组件里的订阅代码不用改,拿到的直接就是带getter的Product实例。
解决方案三:用Angular自带的DatePipe(更推荐)
其实对于日期格式化,Angular已经提供了现成的DatePipe,完全不用在类里写getter,直接在模板里处理更符合Angular的最佳实践:
{{ product.timeCreated | date:'dd/MM/yyyy' }}
这种方式既不用处理类实例化的问题,还能灵活调整日期格式,一举两得。
试试上面的方法,你的格式化日期应该就能正常显示啦!
内容的提问来源于stack exchange,提问作者pk028382
相关产品推荐
相关产品推荐

