如何从代理数组中删除或插入项目?

How to get deleted or inserted item from proxy array?

提问人:Johar Zaman 提问时间:2/28/2019 最后编辑:Johar Zaman 更新时间:12/12/2021 访问量:1629

问:

我正在尝试使用 JavaScript 代理检测对象数组中的更改。

问题:每当数组发生更改(例如删除或插入)时,我都希望获取已删除或插入的项目。

当前代码

target = [{ id: 1, a: 'a' }, { id: 2, a: 'b' }];
proxy = new Proxy(target, {
    get: function (target, property: string, receiver) {
        if (property === 'pop') {
            console.log('deleted object', target[target.length - 1]);
        }
        console.log('get', property);
        // property is index in this case
        return target[property];
    },
    set: function (target, property, value, receiver) {
        console.log('set', property, 'to', value);
        target[property] = value;
        // you have to return true to accept the changes
        return true;
    }
});

当前的想法:我做了一些解决方法从数组中获取已删除的项目,但它仅适用于方法,因为它从数组中删除了最后一项。但是我需要一种方法来获取更改,即使它是使用方法或或进行的。pop()splicepushpop

谢谢。

[更新] 我发现的解决方案:

https://github.com/ElliotNB/observable-slim我使用这个库来检测数组中的更改,我也能够检测数组内嵌套属性的更改。这正是我一直在寻找的。

我使用这个库的原因是因为它使用代理。

JavaScript 数组 es6-proxy

评论

0赞 caesay 2/28/2019
如果要捕获,则必须像为拼接一样编写一个处理程序 - 查看参数以查看将删除的内容,然后在删除数据之前存储数据。冲洗并重复您要处理的每种方法。splicepop
0赞 Johar Zaman 2/28/2019
我试过了,但我没有在这个代理处理程序中得到拼接参数。
0赞 Johar Zaman 2/28/2019
npmjs.com/package/underscore-observe有这个库来观察数组的变化,但这使用的是 Array.observe(),它现在已经过时了。代理是 Array.observe 的替代品,因此应该有一种使用代理来检测这些更改的方法。
0赞 shajji 2/28/2019
代理对你@JoharZaman重要吗?或者其他任何方式也没问题?
1赞 Bergi 2/28/2019
您根本不应该跟踪方法调用,而应该只跟踪索引元素。

答:

0赞 xdeepakv 12/12/2021 #1

我建议不要在 getter 上暴露实际的 traget。您可以创建一个包装函数来支持 cutosom 修饰符。请看下面的例子。

const target = [
  { id: 1, a: "a" },
  { id: 2, a: "b" },
];
const proxy = new Proxy(target, {
  get: function (target, property, receiver) {
    switch (property) {
      case "push":
      case "pop":
      case "slice":
      case "splice":
        return (...arg) => target[property](...arg);
    }
    throw Error("Not supported yet");
  },
});

proxy.push({ id: 3, a: "c" })
console.log(proxy.pop())
console.log(proxy.slice(1,2))
console.log(proxy.pop())

评论

0赞 Bergi 12/12/2021
这几乎不再是一个数组。既不工作也不工作。proxy.lengthproxy[0]
0赞 Selaka Nanayakkara 11/25/2023 #2

参考以下代码:

function observeArrayChanges(array, callback) {
  // Create a proxy for the array
  const arrayProxy = new Proxy(array, {
    // The set handler is called whenever there's an insertion or deletion
    set(target, property, value) {
      const oldValue = target[property];

      // Perform the actual insertion or deletion
      const result = Reflect.set(target, property, value);

      // Check if it's an insertion or deletion
      if (oldValue !== value) {
        // Call the callback with information about the change
        callback({
          type: oldValue === undefined ? 'insert' : 'delete',
          item: oldValue === undefined ? value : oldValue,
        });
      }

      // Return the result of the set operation
      return result;
    },
  });

  return arrayProxy;
}

// Example usage:

const myArray = observeArrayChanges(
  [{ id: 1, a: 'a' }, { id: 2, a: 'b' }],
  (change) => {
    console.log(`Change type: ${change.type}`);
    console.log(`Changed item: `, change.item);
  }
);

// Insert an item
myArray.push({ id: 3, a: 'c' });

// Delete an item
//delete myArray[0];
console.log(myArray.pop())
console.log(myArray.slice(1,2))
console.log(myArray.pop())
console.log(myArray.length)
console.log(JSON.stringify(myArray))