Как выставить состояние localStorage с полимерным стартовым шаблоном PWA 3 - PullRequest
0 голосов
/ 13 ноября 2018

Я использую шаблон стартового пакета Polymer 3 PWA, взятый отсюда: https://github.com/Polymer/pwa-starter-kit/tree/template-typescript

Теперь я хочу установить состояние localStorage, как описано в документации. Поэтому я добавляю файл localstorage.ts

export const saveState = (state) => {
    let stringifiedState = JSON.stringify(state);
    localStorage.setItem('__wtt_store__', stringifiedState);
  }

export const loadState = () => {
    try {
        let json = localStorage.getItem('__wtt_store__') || '{}';
        let state = JSON.parse(json);
        console.log("local storage state:"+state.counter.clicks);

        if (state) {
        return state;
        } else {
        return undefined;  // To use the defaults in the reducers
        }
    } catch { 
        console.log("local storage error");
        return undefined;
    }
  }

и изменил файл store.ts из шаблона:

export const store = createStore(
  state => state as Reducer<RootState, RootAction>,
  loadState(),  // --------- LINE ADDED -----------------
  devCompose(
    lazyReducerEnhancer(combineReducers),
    applyMiddleware(thunk as ThunkMiddleware<RootState, RootAction>))
);

// Initially loaded reducers.
store.addReducers({
  app
});

// ---------  ADDED -----------------
store.subscribe(() => {
  saveState(store.getState());
});

Журнал консоли показывает, что состояние записывается в localStorage и загружается после обновления браузера. Но исходные значения данных компонентов возвращаются к исходным значениям после перезагрузки, а не к значениям сохраненного localStorage?

Что необходимо добавить, чтобы данные из localStorage использовались во время инициализации в веб-компоненте? Я просто пытаюсь сохранить пример "counter" в localStorage из шаблона PWA my-view2.ts. Но безуспешно.

Что нужно сделать, чтобы записать данные счетчика из my-view2.ts шаблона PWA в localStorage и перезагрузить для последующего состояния? Мои решения не работают в соответствии со стандартной процедурой из руководства.

1 Ответ

0 голосов
/ 16 ноября 2018

Я нашел следующее решение.

первопричины: saveState(store.getState()); вызывается каждый раз, когда получено обновление магазина. В шаблоне запуска приложения есть только загруженный редуктор. Редуктор для элемента счетчика не загружается при инициализации приложения и ленивой загрузке. Поэтому любое сохраненное значение в localStore из последнего сеанса теперь перезаписывается новой функцией saveState только с данными магазина приложений. В этом случае перезаписывают ранее сохраненные данные счетчика пустыми данными. Это приводит к пустым данным после загрузки элемента счетчика и инициализации редуктора.

Решение: Во время первоначальной загрузки localStore я сохраняю исходный полный localState из последнего сеанса в переменную, подобную этой:

export let initialLocalState:any={};
export const loadState = () => {
    try {
        let json = localStorage.getItem('__wtt_store__') || '{}';
        let state = JSON.parse(json);
        //console.log("load local app storage state:"+state.counter.clicks);

        if (state) {
            initialLocalState=state;
            //console.log("Original: "+JSON.stringify(initialLocalState))
            return state;
        } else {
            return undefined;  // To use the defaults in the reducers
        }
    } catch { 
        console.log("local storage error");
        return undefined;
    }
  }

Теперь, чтобы избежать перезаписи полных данных с помощью раннего вызова saveState, где не все данные могут быть инициализированы, я объединяю весь контент обратно в хранилище перед сохранением:

export const saveState = (state) => {
    if (state==null) return;

    //ensure that we merge it with the full initial local state received during app start and store creation
    //fill up the last session state with lazy new states
    var merged = Object.assign({}, initialLocalState, state);

    let stringifiedState = JSON.stringify(merged);
    //console.log("Saving: "+stringifiedState);
    localStorage.setItem('__wtt_store__', stringifiedState);
  }

Наконец, я добавил действие в веб-компонент counter.ts для получения начальных данных из localStorage

// load initial data from localStore, if available
store.dispatch(loadfavorite());

Это решение помогает мне придерживаться предложенной структуры компонентов стартового набора PWA с ленивой загрузкой компонентов и редукторов и обеспечивает возможность полного доступа к данным localStorage с последнего сеанса.

...