Rxjs 在 behaviorsubject 中包含深度嵌套的对象
Rxjs include deeply nested objects in behaviorsubject
我开始使用 Rxjs 中的 BehaviorSubject,但在这方面的经验有限。到目前为止,我能够在组件中获取根级参数,但访问嵌套对象会导致 'cannot read property x of undefined'.
类:
export class Basket extends X23Object {
public BasketId: number;
public UserID: number;
public User: User;
public BasketLines: BasketLine[] = [];
}
export class BasketLine extends X23Object {
public BasketLineId: number;
public BasketId: number;
public ProductId: number;
public Quantity: number;
public Product: Product;
public Price: number;
public Name: string;
}
export class Product extends X23Object {
public ProductId: number;
public CategoryId: number;
public Name: string;
public Code: string;
public Price: number;
public Details: string;
public Images: Image[];
public Category: Category;
}
篮子后端服务
GetBasket() {
return this.authHttp.get(this.apiUrl + 'api/GetBasketByUser?id=' + parseInt(this.decodedJwt['userId']), { headers: contentHeaders });
}
篮子服务
private _lines: BehaviorSubject<BasketLine[]> = new BehaviorSubject([new BasketLine]);
get getLines() {
return this._lines.asObservable();
}
loadBasket() {
this.basketBackendService.GetBasket()
.subscribe(
response => {
let lines = <BasketLine[]>response.json().basket.BasketLines;
this._lines.next(lines);
},
error => console.log(error.text())
);
}
模板(片段)
<tr *ngFor="let line of basketService.getLines | async">
<td><img class="login-logo" src="{{ line.Product.Images[0].ThumbUrl }}" width="100%" /></td>
<td><a [routerLink]="['Product', { id: line.ProductId }]"> {{ line.Product.Code }} </a></td>
<td><a [routerLink]="['Product', { id: line.ProductId }]">{{ line.Product.Name }}</a></td>
<td class="text-right">{{ line.Price | currency:'GBP':true:'.2-2' }}</td>
<td class="text-center">{{ line.Quantity }}</td>
<td class="text-right">{{ line.Quantity * line.Price | currency:'GBP':true:'.2-2' }}</td>
<td><button (click)="DeleteLine(line.BasketLineId)">Remove</button></td>
</tr>
如果我删除深层嵌套对象的引用,我会得到预期的返回结果。
我正在尝试使用 BehaviorSubject 来更新多个组件,但不确定这是否是最佳解决方案!
代码对我来说看起来不错,我猜 "deep nested" 你的意思是 line.Product.Code
。如果它与 line.Quantity
一起使用,那么问题很可能不在 BehaviorSubject
中,而是在您的数据结构中。
我不知道你的具体用例是什么,但你根本不需要使用 BehaviorSubject
和 async
管道。
对于 BasketService
你可以只使用:
export class BasketService {
lines: BasketLine[];
// ...
loadBasket() {
this.basketBackendService.GetBasket().subscribe(
response => {
this.lines = <BasketLine[]>response.json().basket.BasketLines;
},
error => console.log(error.text())
);
}
}
然后只渲染它:
<tr *ngFor="let line of basketService.lines">
// ...
</tr>
我开始使用 Rxjs 中的 BehaviorSubject,但在这方面的经验有限。到目前为止,我能够在组件中获取根级参数,但访问嵌套对象会导致 'cannot read property x of undefined'.
类:
export class Basket extends X23Object {
public BasketId: number;
public UserID: number;
public User: User;
public BasketLines: BasketLine[] = [];
}
export class BasketLine extends X23Object {
public BasketLineId: number;
public BasketId: number;
public ProductId: number;
public Quantity: number;
public Product: Product;
public Price: number;
public Name: string;
}
export class Product extends X23Object {
public ProductId: number;
public CategoryId: number;
public Name: string;
public Code: string;
public Price: number;
public Details: string;
public Images: Image[];
public Category: Category;
}
篮子后端服务
GetBasket() {
return this.authHttp.get(this.apiUrl + 'api/GetBasketByUser?id=' + parseInt(this.decodedJwt['userId']), { headers: contentHeaders });
}
篮子服务
private _lines: BehaviorSubject<BasketLine[]> = new BehaviorSubject([new BasketLine]);
get getLines() {
return this._lines.asObservable();
}
loadBasket() {
this.basketBackendService.GetBasket()
.subscribe(
response => {
let lines = <BasketLine[]>response.json().basket.BasketLines;
this._lines.next(lines);
},
error => console.log(error.text())
);
}
模板(片段)
<tr *ngFor="let line of basketService.getLines | async">
<td><img class="login-logo" src="{{ line.Product.Images[0].ThumbUrl }}" width="100%" /></td>
<td><a [routerLink]="['Product', { id: line.ProductId }]"> {{ line.Product.Code }} </a></td>
<td><a [routerLink]="['Product', { id: line.ProductId }]">{{ line.Product.Name }}</a></td>
<td class="text-right">{{ line.Price | currency:'GBP':true:'.2-2' }}</td>
<td class="text-center">{{ line.Quantity }}</td>
<td class="text-right">{{ line.Quantity * line.Price | currency:'GBP':true:'.2-2' }}</td>
<td><button (click)="DeleteLine(line.BasketLineId)">Remove</button></td>
</tr>
如果我删除深层嵌套对象的引用,我会得到预期的返回结果。
我正在尝试使用 BehaviorSubject 来更新多个组件,但不确定这是否是最佳解决方案!
代码对我来说看起来不错,我猜 "deep nested" 你的意思是 line.Product.Code
。如果它与 line.Quantity
一起使用,那么问题很可能不在 BehaviorSubject
中,而是在您的数据结构中。
我不知道你的具体用例是什么,但你根本不需要使用 BehaviorSubject
和 async
管道。
对于 BasketService
你可以只使用:
export class BasketService {
lines: BasketLine[];
// ...
loadBasket() {
this.basketBackendService.GetBasket().subscribe(
response => {
this.lines = <BasketLine[]>response.json().basket.BasketLines;
},
error => console.log(error.text())
);
}
}
然后只渲染它:
<tr *ngFor="let line of basketService.lines">
// ...
</tr>