如何显示 Observable?
How to display Observable?
这是产品的界面
export interface Product{
id?:string,
name:string,
price:string;
quantity:string;
tags:Tags[];
description:string;
files: File[];
}
在我的 home.component.ts 文件中我有这个
export class HomeComponent implements OnInit {
constructor(
private store:Store<fromRoot.AppState>
) { }
products$!: Observable<Product[]>;
products_list! :Product[];
ngOnInit(): void {
this.store.dispatch(new productActions.LoadProducts());
^^^^此函数从 effect.ts
调用 loadproducts$
this.products$ = this.store.pipe(select(fromProduct.getCreatedProducts));
}
}
products$ 现在是一个观察对象来显示它,我使用 Async | json
。下面是我的 html 代码。
<div *ngFor = "let p of products$ | async">
<h1>
{{p.name}}
</h1>
</div>
我在这里作证action.ts
export enum UserActionTypes{
LOAD_CREATED_PRODUCTS = '[User] Load Created Products',
LOAD_CREATED_PRODUCTS_SUCCESS = '[User] Load Created Products Success',
LOAD_CREATED_PRODUCTS_FAIL = '[User] Load Created Products Fail'
}
export class LoadProducts implements Action{
readonly type = UserActionTypes.LOAD_CREATED_PRODUCTS
}
export class LoadProductsSuccess implements Action{
readonly type = UserActionTypes.LOAD_CREATED_PRODUCTS_SUCCESS
constructor(public payload:Product[]){}
}
export class LoadProductsFail implements Action{
readonly type = UserActionTypes.LOAD_CREATED_PRODUCTS_FAIL
constructor(public payload:string){}
}
export type action = LoadProducts | LoadProductsSuccess | LoadProductsFail ;
这是我的product.reducer.ts
export interface SoldProductState extends EntityState<Product>{
selectedProductId: string,
loading:boolean,
loaded:boolean,
error:string
}
export const productAdapter:EntityAdapter<Product> = createEntityAdapter<Product>({
selectId:Product=>Product.id
});
export const defaultProduct:SoldProductState={
ids:[],
entities:{},
selectedProductId:"",
loading:false,
loaded:false,
error:""
}
export const initialState = productAdapter.getInitialState(defaultProduct);
export function productReducer(
state = initialState,
action:productActions.action
):SoldProductState{
这是我的 LoadCreatedProduct
switch(action.type){
case productActions.UserActionTypes.LOAD_CREATED_PRODUCTS:{
return {
...state,
loading:true,
loaded:false
};
}
这是我的 LoadCreatedProductSuccess
case productActions.UserActionTypes.LOAD_CREATED_PRODUCTS_SUCCESS:{
return productAdapter.addMany(action.payload,{
...state,
entities:{},
loaded:true,
loading:false
});
}
default:{
return state;
}
}
}
这里我添加了effect.ts
@Effect()
loadproducts$:Observable<Action> = this.action$.pipe(
ofType<productActions.LoadProducts>(
productActions.UserActionTypes.LOAD_CREATED_PRODUCTS
),
mergeMap((actions:productActions.LoadProducts)=>
this.product_service.getCreatedProducts().pipe(
map(
(products:Product[])=>
new productActions.LoadProductsSuccess(products)
),
catchError(err=>of(new productActions.LoadProductsFail(err)))
))
)
现在,如果我加载页面,所有内容都会正确显示,如下所示
如果我导航到另一个页面并返回,列表会加倍,如下所示
如果我访问另一个页面 n 次,列表将显示 n 次。
但如果我重新加载页面,它就可以正常工作。
我是初学者,不知道如何解决这个问题。
我希望我能够解释我的问题。
谢谢。
addMany
(productAdapter.addMany) 将新项目附加到现有项目,这会导致数据重复。
使用 setAll
而不是 addMany
将所有现有项目替换为新项目:
这是产品的界面
export interface Product{
id?:string,
name:string,
price:string;
quantity:string;
tags:Tags[];
description:string;
files: File[];
}
在我的 home.component.ts 文件中我有这个
export class HomeComponent implements OnInit {
constructor(
private store:Store<fromRoot.AppState>
) { }
products$!: Observable<Product[]>;
products_list! :Product[];
ngOnInit(): void {
this.store.dispatch(new productActions.LoadProducts());
^^^^此函数从 effect.ts
调用 loadproducts$ this.products$ = this.store.pipe(select(fromProduct.getCreatedProducts));
}
}
products$ 现在是一个观察对象来显示它,我使用 Async | json 。下面是我的 html 代码。
<div *ngFor = "let p of products$ | async">
<h1>
{{p.name}}
</h1>
</div>
我在这里作证action.ts
export enum UserActionTypes{
LOAD_CREATED_PRODUCTS = '[User] Load Created Products',
LOAD_CREATED_PRODUCTS_SUCCESS = '[User] Load Created Products Success',
LOAD_CREATED_PRODUCTS_FAIL = '[User] Load Created Products Fail'
}
export class LoadProducts implements Action{
readonly type = UserActionTypes.LOAD_CREATED_PRODUCTS
}
export class LoadProductsSuccess implements Action{
readonly type = UserActionTypes.LOAD_CREATED_PRODUCTS_SUCCESS
constructor(public payload:Product[]){}
}
export class LoadProductsFail implements Action{
readonly type = UserActionTypes.LOAD_CREATED_PRODUCTS_FAIL
constructor(public payload:string){}
}
export type action = LoadProducts | LoadProductsSuccess | LoadProductsFail ;
这是我的product.reducer.ts
export interface SoldProductState extends EntityState<Product>{
selectedProductId: string,
loading:boolean,
loaded:boolean,
error:string
}
export const productAdapter:EntityAdapter<Product> = createEntityAdapter<Product>({
selectId:Product=>Product.id
});
export const defaultProduct:SoldProductState={
ids:[],
entities:{},
selectedProductId:"",
loading:false,
loaded:false,
error:""
}
export const initialState = productAdapter.getInitialState(defaultProduct);
export function productReducer(
state = initialState,
action:productActions.action
):SoldProductState{
这是我的 LoadCreatedProduct
switch(action.type){
case productActions.UserActionTypes.LOAD_CREATED_PRODUCTS:{
return {
...state,
loading:true,
loaded:false
};
}
这是我的 LoadCreatedProductSuccess
case productActions.UserActionTypes.LOAD_CREATED_PRODUCTS_SUCCESS:{
return productAdapter.addMany(action.payload,{
...state,
entities:{},
loaded:true,
loading:false
});
}
default:{
return state;
}
}
}
这里我添加了effect.ts
@Effect()
loadproducts$:Observable<Action> = this.action$.pipe(
ofType<productActions.LoadProducts>(
productActions.UserActionTypes.LOAD_CREATED_PRODUCTS
),
mergeMap((actions:productActions.LoadProducts)=>
this.product_service.getCreatedProducts().pipe(
map(
(products:Product[])=>
new productActions.LoadProductsSuccess(products)
),
catchError(err=>of(new productActions.LoadProductsFail(err)))
))
)
现在,如果我加载页面,所有内容都会正确显示,如下所示
如果我导航到另一个页面并返回,列表会加倍,如下所示
如果我访问另一个页面 n 次,列表将显示 n 次。
但如果我重新加载页面,它就可以正常工作。 我是初学者,不知道如何解决这个问题。 我希望我能够解释我的问题。 谢谢。
addMany
(productAdapter.addMany) 将新项目附加到现有项目,这会导致数据重复。
使用 setAll
而不是 addMany
将所有现有项目替换为新项目: