typescript 在js中观察本地存储变化

cnh2zyt3  于 2023-01-14  发布在  TypeScript
关注(0)|答案(7)|浏览(222)

我有一个单页的应用程序,我需要对本地存储的每一个变化作出React,它看起来像:

MyComponent {
    
    someFuncWhichIsCalledEveryTimeWhenLocalStorageChanges() {
        console.log('local storage changed!');
    }
    
    funcThatChangesLocalStorage() {
        localstorage.setItem('key',val);
        localstorage.getItem('key')
    }
    
    }

我尝试使用本地存储事件:

window.addEventListener('storage', function(event){
       ...
});

但那不起作用...所以我考虑使用Observable<>,只是不知道如何正确地实现它。

mrphzbgm

mrphzbgm1#

来自MDN docs: Window storage event的巨大警告

[window.addEventListener('storage', ...)]无法在进行更改的同一页面上工作-它实际上是域中其他页面使用存储同步所做更改的一种方式。
所以这可能就是为什么它对你不起作用(对我也一样)--你试图在同一页的其他部分回应这个听众。

gj3fmq9x

gj3fmq9x2#

您可以使用一个函数来创建对象的代理方法

function watchAnyObject(
  object = {},
  methods = [],
  callbackBefore = function () {},
  callbackAfter = function () {},
) {
  for (let method of methods) {
    const original = object[method].bind(object);
    const newMethod = function (...args) {
      callbackBefore(method, ...args);
      const result = original.apply(null, args);
      callbackAfter(method, ...args);
      return result;
    };
    object[method] = newMethod.bind(object);
  }
}

像这样使用它

watchAnyObject(
  window.localStorage,
  ['setItem', 'getItem', 'removeItem'],
  (method, key, ...args) =>
    console.log(`call ${method} with key ${key} and args ${args}`),
);

可以在组件构造函数中添加侦听器 * someFuncWhichIsCalledEveryTimeWhenLocalStorageChanges *

constructor() {
  watchAnyObject(window.localStorage, ['setItem', 'getItem', 'removeItem'], this.someFuncWhichIsCalledEveryTimeWhenLocalStorageChanges);
}
eqzww0vc

eqzww0vc3#

**localDataStorage**接口(HTML5 localStorage API的一个方便的 Package 器)可以在发生存储事件的同一 * 页面/选项卡/窗口上方便地触发更改事件。免责声明:我是界面的作者。

安装localDataStorage后,此示例代码将让您看到这些更改事件:

function nowICanSeeLocalStorageChangeEvents( e ) {
    console.log(
        "subscriber: "    + e.currentTarget.nodeName + "\n" +
        "timestamp: "     + e.detail.timestamp + " (" + new Date( e.detail.timestamp ) + ")" + "\n" +
        "prefix: "        + e.detail.prefix    + "\n" +
        "message: "       + e.detail.message   + "\n" +
        "method: "        + e.detail.method    + "\n" +
        "key: "           + e.detail.key       + "\n" +
        "old value: "     + e.detail.oldval    + "\n" +
        "new value: "     + e.detail.newval    + "\n" +
        "old data type: " + e.detail.oldtype   + "\n" +
        "new data type: " + e.detail.newtype
    );
};
document.addEventListener(
    "localDataStorage"
    , nowICanSeeLocalStorageChangeEvents
    , false
);
gwbalxhn

gwbalxhn4#

如果你想监听同一个文档中的存储变化事件,可以像下面这样增加一个存储变化事件发射函数,当你使用localStorage.setItem(“xx”,“xx”),并且在它之后触发这个函数,你就会检测到这个事件~

export function emitStorageChangedEvent() {
  const iframeEl = document.createElement("iframe");
  iframeEl.style.display = "none";
  document.body.appendChild(iframeEl);

  iframeEl.contentWindow?.localStorage.setItem("t", Date.now().toString());
  iframeEl.remove();
}
blpfk2vs

blpfk2vs5#

简化的解决方案!

const localStore = localStorage.setItem;

localStorage.setItem = function(key, value) {
  const event = new Event('localUpdated');
        event.key = key; 
        event.value = value; 
  
  document.dispatchEvent(event);
  localStore.apply(this, arguments);
};

const localStoreHandler = function(e) {
  console.log(`👉 localStorage.set('${e.key}', '${e.value}') updated`);
};

document.addEventListener("localUpdated", localStoreHandler, false);

localStorage.setItem('username', 'amoos');

// After 2 second
setTimeout( ()=>  localStorage.setItem('username', 'rifat'), 2000)
g9icjywg

g9icjywg7#

在另一个文档的上下文中修改存储区域(localStorage或sessionStorage)时,将激发storage事件。
https://developer.mozilla.org/en-US/docs/Web/Events/storage

相关问题