Избегайте перезагрузки изображения при обновлении состояния - PullRequest
0 голосов
/ 10 мая 2019

Я использую NGXS в качестве моего государственного менеджера. У меня есть объект "menuItems", который заполняет мой компонент "sidenav":

export const menuItems: Array<MenuItem> = [


{
    icon: 'assets/circle-logo.png',
    label: 'Home',
    route: '/home',
    selected: false
  },
  {
    icon: 'assets/circle-logo.png',
    label: 'Customers',
    route: '/customers',
    selected: false
  },
  {
    icon: 'assets/circle-logo.png',
    label: 'Entries',
    route: '/entries',
    selected: false
  }];

когда приложение загружается в первый раз, изображение в свойстве "icon" загружается нормально.

enter image description here

Состояние обновляется, когда я нажимаю на элемент из моей sidenav:

enter image description here

Затем в состояние отправляется индекс, чтобы изменить выбранное свойство на «true» и выделить элемент, как показано на рисунке выше.

Моя проблема в том, что когда я обновляю состояние «menuItems», «logo-image» снова перезагружается. Я немного "моргнул" на экране, когда изображение снова загружается.

enter image description here

Это код моего состояния sidenav:

import { State, Action, StateContext } from '@ngxs/store';
import { MenuItem } from '@shared/types';
import { menuItems } from '@components/sidenav/menu-items';

export class SelectMenuItem {
  static readonly type = 'SelectMenuItem';
  constructor(public itemIndex: number) {}
}

@State<Array<MenuItem>>({
  name: 'menuItems',
  defaults: menuItems
})
export class SideNavState {
  @Action(SelectMenuItem)
  selectMenuItem(ctx: StateContext<Array<MenuItem>>, action: SelectMenuItem) {
    const { getState, setState } = ctx;
    const { itemIndex } = action;
    const state = getState();
    const currentItem = state.findIndex(s => s.selected);

    if (currentItem !== itemIndex) {
      const newState = state.map((item, index) => {
        if (currentItem > -1 && currentItem === index) {
          item = { ...item, selected: false };
        }
        if (itemIndex === index) {
          item = { ...item, selected: true };
        }
        return item;
      });
      setState(newState);
    }
  }
}

Правильно ли я обновляю состояние или есть обходной путь для этого поведения?

1 Ответ

1 голос
/ 10 мая 2019

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

Я бы предложил по-другому моделировать ваше состояние, например

export class SelectMenuItem {
  static readonly type = 'SelectMenuItem';
  constructor(public itemIndex: number) {}
}

// In the state model, capture the selected item/index
// separate from the list of menu items.
interface MenuItemStateModel { 
  selectedItem: number,
  menuItems: MenuItem[]
}

@State<MenuItemStateMode>({
  name: 'menuItems',
  defaults: {
    selectedItem: null,
    menuItems: []
  }
})
export class MenuItemState { 

  @Action(SelectMenuItem)
  selectItem({patchState}: StateContext<MenuItemStateModel>, action: SelectMenuItem) { 
    patchState({selectedItem: action.itemIndex});
  }

  // .. Load the menu items from API (or hardcoded?)

}

Затем удалите свойство selected из вашего типа menuItem. В шаблоне, если вы хотите показать его выделенным, вы можете связать стиль в зависимости от того, itemIndex === state.selectedItem.

Таким образом, вы не изменяете список, когда элементы выбраны / не выбраны.

...