Слияние состояния и статических данных для отображения в Angular с помощью ngrx / store

Я новичок в магазине ngrx, и мне трудно понять, как эффективно связать состояние моего приложения со статическими объектами, которые управляют моими компонентами.

items.ts

export class Item {
    id: number;
    name: string;
    count: number;
    need: number;
}

export class ItemState {
    id: number;
    count: number;
}

export class ItemStateAction implements Action {
    type: string;
    id: number;
    count: number;
}

export function itemReducer(
    state: ItemState,
    action: ItemStateAction
) {
    switch (action.type) {
        case SET_VALUE:
            if (state.id === action.id) {
                return (state. = action.count);
            }
        default:
            return state;
    }
}

Я делаю приложение с заранее определенным списком элементов, которое позволяет пользователю регулировать количество каждого элемента.

У меня есть ItemListComponent, который отвечает за выборку элементов из ItemService, который просто возвращает Observable<Item[]>, импортированный из статического файла.

item.service.ts

...
import { Item } from "./item";
import { ITEMS } from "./static-items";

@Injectable()
export class ItemService {
    constructor() {}

    getItems(): Observable<Item[]> {
        return of(ITEMS);
    }
}

item-list.component.ts

...
import { ItemService } from "../item.service";
import { Item } from "../item";

export class ItemListComponent implements OnInit {
    items: Item[];

    constructor(private itemService: ItemService) {}

    ngOnInit() {
        this.getItems();
    }

    getItems(): void {
        this.itemService
            .getItems()
            .subscribe(items => (this.items = items));
    }
}

Должен ли я запросить магазин в компоненте списка элементов (родительский) и объединить Observable<Item[]> с Observable<ItemState[]> из магазина? Или мне следует использовать статический элемент и запрашивать в магазине конкретное состояние элемента в подкомпоненте элемента? Я знаю, что этот субкомпонент должен быть «тупым», поэтому последнее, похоже, идет вразрез с этим.

Я также использую Items в части другой структуры, где подмножество содержится в массиве.

Модель для другого взгляда:

export class Requirement {
    id: number;
    items: Item[];
}

//example
//Requirement[] = [ {'id': 1, items: [{'id': 1, 'name': 'Apple', need: 3, count: 0}] },
//  {'id': 2, items: [{'id': 1, 'name': 'Apple', need: 2, count: 0}] }] 

Для этой структуры мне нужно было бы получить состояние элемента из хранилища, а затем назначить счетчики для каждого элемента в каждом из требований или запрашивать хранилище каждый раз, когда подкомпонент элемента визуализируется для точного подсчета. Есть ли «лучшая практика» для такого рода вещей? Извините, если это слишком непонятно или абстрактно.


person tedski    schedule 18.03.2018    source источник
comment
у вас есть какой-либо тип хранилища? вы должны определить редуктор, который изменяет состояние вашего хранилища, и действия, которые вызывают конкретный редуктор   -  person Ricardo    schedule 18.03.2018
comment
Обновлен редуктор и состояние элемента. Я больше задаю вопрос об архитектуре, например, где я должен изменять / запрашивать состояние моего магазина   -  person tedski    schedule 18.03.2018


Ответы (1)


В свой сервис нужно импортировать магазин из ngrx

import { Store } from "@ngrx/store"
@Injectable()
export class MyService {

constructor(private store: Store<any>) { }

getItems() {
   return this.store.select("items")
}
}

метод getItems выберет из вашего магазина список товаров. "предметы" должны быть определены как часть вашего магазина в объявлении модуля.

для изменения состояния вашего магазина лучше, если вы объявите класс, содержащий действие типа, которое соответствует действиям в вашем редукторе (SET_VALUE)

export class SetValue implements Action {
    readonly type = SET_VALUE
    constructor(public value: any) { }
}

а затем, чтобы вызвать это действие, вы можете просто объявить действие класса и передать его в магазин

setValue(value:any) {
    this.store.dispatch(new SetValue(value))
  }

ваш редуктор будет выглядеть

export function itemReducer(
    state: ItemState = staticValues,
    action: ItemStateAction
) {
    switch (action.type) {
        case SET_VALUE:
            if (state.id === action.id) {
                return (state. = action.count);
            }
        default:
            return state;
    }
}

так я обычно делаю, дайте мне знать, если это прояснит ваш вопрос

person Ricardo    schedule 18.03.2018
comment
Итак, как бы мне совместить это со статическими данными (имя и т. Д., Импортированными из static-items.ts). Вы бы оставили это в магазине? - person tedski; 18.03.2018
comment
вам нужно объявить хранилище (редуктор) со значением по умолчанию, поместите туда эти статические данные - person Ricardo; 18.03.2018