Polymer를 통해 로컬로 저장할 여러 탭의 동기화를 주의할 때

11203 단어 Polymerlocal-storage

Polymer에서 로컬 스토리지 사용


Polymer 로컬 스토리지를 사용하려면 app-storageapp-localstorage-document 레이블을 사용합니다.
iron-localstorage지금은 deprecated입니다.app-localstorage-document 플래그는 로컬 스토리지 기기가 변경될 때data-changed 이벤트가 발생합니다.
이 이벤트가 발생하면 event.detail.value 또는 탭의 data 속성에서 값을 얻을 수 있습니다.
예를 들면 다음과 같다.
<dom-module id="demo">
  <template>
    <app-localstorage-document id="storage" key="hoge"></app-localstorage-document>
  </template>

  <script>
    Polymer({
      is: 'demo',
      listeners: {
        'data-changed': '_dataChanged',
      },
      setValue: function(value) {
        this.$.storage.set('data', value);
      },
      _dataChanged: function(event) {
        console.log(event.detail.value);
      },
    });
  </script>
</dom-module>
demo 요소를 사용하여 여러 탭에서 브라우저를 열 때 setValue 탭의 값은 다른 탭에서 컨트롤러로 출력됩니다.

현상


다양한 브라우저 (최신 버전) 에서 이 설치를 시도한 결과는 다음과 같다.
Chrome
Firefox
Safari
IE11
Edge
OK
OK
OK
NG
NG
app-localstorage-document 태그 설치 확인 결과 다음과 같습니다.
app-localstorage-document.html#L82
      attached: function() {
        this.listen(window, 'storage', '__onStorage');
        this.listen(
            window.top,
            'app-local-storage-changed',
            '__onAppLocalStorageChanged');
      },
window.onstorage 이벤트에서 로컬 저장소의 변경을 받고 호출__onStorage합니다.
app-localstorage-document.html#L182
      __onStorage: function(event) {
        if (event.key !== this.key ||
            event.storageArea !== this.storage) {
          return;
        }
        this.syncToMemory(function() {
          this.set('data', this.__parseValueFromStorage());
        });
      },
__onStorage에서 호출__parseValueFromStorage.
app-localstorage-document.html#L204
      __parseValueFromStorage: function() {
        try {
          return JSON.parse(this.storage.getItem(this.key));
        } catch(e) {
          console.error('Failed to parse value from storage for', this.key);
        }
      },
__parseValueFromStorage에서 this.storage를 통해 실제 로컬 저장소에서 값을 얻는다.
MS 시스템의 브라우저에서 window.onstorage 활성 시점에 저장된 컨텐트는 덮어쓰지 않은 것 같습니다.
(실제 개발자 도구를 사용하여 확인한 결과 로컬에 저장된 값은 이벤트를 받을 때 여전히 낡았지만 이벤트 처리가 끝난 후에 확인한 결과 새로운 값이었다.)

대응


https://developer.mozilla.org/en-US/docs/Web/API/WindowEventHandlers/onstorage
의 사이트에서 발견 사건 대상은 newValueoldValue로 설정되었다.
실제로 그 값을 확인한 결과 IE11과 Edge에도 변경된 값이 포함되어 있습니다.
따라서 아까의 예를 간단하게 개작하면 다음과 같다.
<dom-module id="demo">
  <template>
    <app-localstorage-document id="storage" key="hoge"></app-localstorage-document>
  </template>

  <script>
    Polymer({
      is: 'demo',
      setValue: function(value) {
        this.$.storage.set('data', value);
      },
      _dataChanged: function(event) {
        console.log(event.newValue);
      },
      ready: function() {
        this.listen(window, 'storage', '_dataChanged');
      }
    });
  </script>
</dom-module>
이렇게 하면 IE11과 Edge도 값을 동기화할 수 있습니다.
그러나 이 코드는 문제가 있다. 로컬에 저장된 열쇠 등을 검사하지 않았기 때문에 앞에서 말한 __onStorage처럼 검사가 필요하다.

isse 썼어요.


나는 위의 내용을 issue로 만들었기 때문에 수정할 수 있다면 좋겠다고 생각한다.
(시간이 있으면 홍보하고 싶어요.)

좋은 웹페이지 즐겨찾기