angular - ngrx store subscribe to change in item in collection -
i'm using latest angular 4 , @ngrx/store. let's have object:
export interface layer { id: number; name: string; selected: boolean; data: any; }
i have created component user can select or deselect layer. i'm trying use show , hide layers in mapbox-gl. selected
property of layer object gets turned true or false.
i created actions:
export const show_layer = '[layers] show layer'; export const hide_layer = '[layers] hide layer'; export class showlayeraction implements action { readonly type = show_layer; constructor(public payload: number) { } } export class hidelayeraction implements action { readonly type = hide_layer; constructor(public payload: number) { } } export type actions = showlayeraction | hidelayeraction;
i created reducer:
export interface layersstate { ids: number[]; entities: { [id: number]: layer }; } const initialstate: layersstate = { ids: [ 1 ], entities: { 1: { id: 1, mapboxid: 'stations', name: 'stations', selected: true, data: { 'id': 'stations', 'type': 'symbol', 'source': { type: 'vector', url: 'mapbox://oliverschenk.3avhfmqh' }, 'layout': { 'visibility': 'visible', 'text-field': '{name}', 'text-size': 11, 'text-offset': [2.5, -1] }, 'paint': { 'text-color': '#f1be48', 'text-opacity': 0.5 }, 'source-layer': 'stations-629auy' } } } }; export function reducer(state = initialstate, action: layers.actions): layersstate { switch (action.type) { case layers.show_layer: case layers.hide_layer: return { ids: state.ids, entities: object.assign({}, state.entities, { [action.payload]: object.assign({}, state.entities[action.payload], { selected: (action.type == layers.show_layer) }) }) } default: return state; } } export const getids = (state: layersstate) => state.ids; export const getentities = (state: layersstate) => state.entities;
in mapbox-gl container need told when state changes can call appropriate mapbox api method either show or hide layer based on selected
field.
in constructor subscribe layers state.
constructor(private store: store<fromroot.state>) { store.select(fromroot.getlayers) .do(layers => this.initlayers(layers)) .take(1) .switchmap(layers => store.select(fromroot.getlayers)) .skip(1) .do(layers => this.updatelayervisibility(layers)) .subscribe((layers) => {}); }
the first part takes first item , initialises layers in mapbox first pass, following take care of showing or hiding layer.
the issue returns layers , not ones changed. there way can organise code better somehow update visibility of layer selected
property changed?
at stage have 1 layer, surely it's not best solution keep looping through entire layers collection , update them when 1 layer's visibility changes?
Comments
Post a Comment