Ngrx 选择器返回部分对象

问题描述 投票:0回答:1

我正在尝试设置 ngrx 并且我已经快到了,我只是无法让选择器返回正确对象类型的 Observable。目前它正在返回 Partial< Observable < Product > > 而不仅仅是 Observable< Product >

我的选择器代码正确吗?

型号:

export class Product {

    id: string | undefined;
    product: string | undefined;
    price: number | undefined;

    constructor(init?: Partial<any>) {

        if (init) {
            if ('id' in init) {
                this.id = init.id;
            }
            if ('product' in init) {
                this.product = init.product;
            }
            if ('price' in init) {
                this.price = init.price;
            }
        }
    }
}

我的应用程序状态:

I have several sub-states within my AppState.
I am trying to select one at a time.

export const initialState: AppState = {
    products: productsInitialState,
    customers: customersInitialState,
  }

选择器:

export const selectProductsState = (state: AppState) => state.products;

export const selectProducts = createSelector(
  selectProductsState,
  state => new Product({id: state.id, product: state.product, price: state.price})
);

成分:

products: Product[] = [];

// I am getting an error that res is of type Partial<Observable<Product>>

this.store.select(selectProducts).subscribe((res: Product[]) => {
      this.products = blah... do manipulation of the data here...
});
angular rxjs ngrx ngrx-store
1个回答
0
投票

这是一个没有使用 Partial 作为构造函数的示例。

最后,你可以看到我使用的订阅者没有部分格式。

app.config.ts

import { ApplicationConfig } from '@angular/core';
import { provideRouter } from '@angular/router';

import {
  createAction,
  createReducer,
  createSelector,
  on,
  props,
  provideStore,
} from '@ngrx/store';

import { routes } from './app.routes';

export class Product {
  id?: string;
  product?: string;
  price?: number;
  constructor(id: string, product: string, price: number) {
    this.id = id;
    this.product = product;
    this.price = price;
  }
}

export type ProductState = {
  id?: string;
  product?: string;
  price?: number;
};

export type AppState = {
  products: ProductState[];
};

export const productsInitialState = [
  {
    id: '1',
    product: 'example',
    price: 0.0,
  },
];

export const initialState: AppState = {
  products: productsInitialState,
};

export const selectProductsState = (state: AppState) => state.products;

export const selectProducts = createSelector(selectProductsState, (state) => {
  return state;
});

/**
 * Boilerplate
 */
export const action = createAction(
  '[Example consume SELECT]',
  props<Product>()
);

export const productReducer = createReducer(
  initialState,
  on(action, (state, { id, product, price }) => {
    return { ...state, products: [...state.products, { id, product, price }] };
  })
);

export const appConfig: ApplicationConfig = {
  providers: [
    provideStore({ products: productReducer }),
    provideRouter(routes),
  ],
};

app.component.ts

    import { Component } from '@angular/core';
    import { CommonModule, DecimalPipe } from '@angular/common';
    import { RouterOutlet } from '@angular/router';
    import { Store } from '@ngrx/store';
    import { AppState, Product, action, selectProducts } from './app.config';
    
    @Component({
      selector: 'app-root',
      standalone: true,
      imports: [CommonModule, DecimalPipe, RouterOutlet],
      template: `
        <h1>{{ title }}</h1>
        <ul>
          @for(product of products; track product.id) {
          <li>
            <span>
              {{ product.id }}
              {{ product.product }}
              {{ product.price | number }}
            </span>
          </li>
          } @empty { 0 products. }
        </ul>
      `,
    })
    export class AppComponent {
      title = 'ngrx-selector-returns-a-partial-object';
      products?: Product[];
      constructor(private store: Store<AppState>) {
        //Add
        this.store.dispatch(action(new Product('2', 'my new product', 0.02)));
        //Example
        this.store.select(selectProducts).subscribe({
          next: (value: any) => {
            console.dir(value);
            this.products = value.products;
          },
        });
}}
© www.soinside.com 2019 - 2024. All rights reserved.