如何订阅对象更改?

Eyk*_*ein 1 javascript

我想知道如何像Redux一样订阅JavaScript对象的更改。我通读了许多JS文档,但是找不到解决此问题的非弃用方法(Object.protype.watch()以及Object.observe()不赞成使用)。此外,我阅读了一些有关此主题的Stackoverflow问题,但它们都已存在至少5年。为了形象化我的问题,我将举一个例子。

这可能是我要注意的对象:

const store = {
    anArray = [
    'Hi',
    'my',
    'name',
    'is'
  ]
}
Run Code Online (Sandbox Code Playgroud)

..这是一个更改store对象的函数:

function addAName() {
    store.anArray.push('Bob')
}
Run Code Online (Sandbox Code Playgroud)

在此示例中,我的目标是每次store对象更改时触发以下功能

function storeChanged() {
    console.log('The store object has changed!')
}
Run Code Online (Sandbox Code Playgroud)

先感谢您!

Ale*_*era 5

您是否尝试过使用ECMA6中的代理?我认为这就是您要寻找的东西,您只需要定义一个函数作为Proxy验证程序的集合即可,如下所示:

let validator = {
    set: function(target, key, value) {
        console.log(`The property ${key} has been updated with ${value}`);
        return true;
    }
};
let store = new Proxy({}, validator);
store.a = 'hello';
// console => The property a has been updated with hello
Run Code Online (Sandbox Code Playgroud)


Mac*_*eja 5

要解决这个问题而不需要任何间接(使用对象),您可以使用代理。

通过包装所有对象,observable您可以自由编辑您的商店并_base跟踪哪个属性已更改。

const observable = (target, callback, _base = []) => {
  for (const key in target) {
    if (typeof target[key] === 'object')
      target[key] = observable(target[key], callback, [..._base, key])
  }
  return new Proxy(target, {
    set(target, key, value) {
      if (typeof value === 'object') value = observable(value, callback, [..._base, key])
      callback([..._base, key], target[key] = value)
      return value
    }
  })
}

const a = observable({
  a: [1, 2, 3],
  b: { c: { d: 1 } }
}, (key, val) => {
  console.log(key, val);
})

a.a.push(1)

a.b.c.d = 1
a.b = {}
a.b.c = 1
Run Code Online (Sandbox Code Playgroud)