2016-09-29 62 views
0

我使用代理检测对象何时被修改(然后将其保存到磁盘)。这适用于代理对象的简单属性,但对对象属性的修改失败。如何递归捕获对象的所有更改?

var obj = { 
    p1 = "Hello", 
    a1 = [] 
} 

var dirtyHandler = { 
    set: function(obj, prop, value) { 
     markDirty(obj); 
     obj[prop] = value; 
     return true; 
    } 
}; 

var proxied = new Proxy(obj, dirtyHandler); 
proxied.p1 = "World"; // <-- proxy detects modification 
proxied.a1.push({'foo': 3}); // <-- proxy does not detect modification 

有谁知道如何递归检测任何修改在我对象(a1.push(...),A1 [0]包含.foo = 4,等等)?

+0

http://stackoverflow.com/questions/5100376/how-to-watch-for-array-changes – epascarello

+1

也为数组做一个代理?可能动态获取任意属性? – Bergi

回答

0

下面是我最终解决这个问题的方法。

首先我为所有我关心的已知对象(未显示)添加一个代理。在处理程序上的每一套呼叫代理我检查,如果值已经是一个代理,如果没有,代替一个:

var DirtyHandler = function(root) { 
    this.root = root; 

    this.set = (obj, prop, value) => { 
     if (!dirtyIgnores[prop]) { 
      debug('Dirty: ' + prop + ' of ' + obj.commitId); 
      markDirty(this.root); 
     } 
     if (value && typeof value === 'object') { 
      value = new Proxy(value, this); 
     } 
     obj[prop] = value; 
     return true; 
    }; 
} 
0

我通过一个目标在GitHub上发布的库(Observable Slim)是递归迭代对象并在所有对象上应用代理。它使您能够监视单个目标对象下发生的所有更改,而不管它们的嵌套程度如何。它还有一些额外的功能:

  • 无论何时发生更改,都可以回报指定的回调。
  • 会阻止用户尝试代理代理服务器。
  • 保持已经代理了哪些对象的存储,并将重新使用现有代理而不是创建新代理(非常重要的性能影响)。
  • 允许用户从子对象向上遍历并检索父对象。
  • 在ES5中编写,并与Proxy Polyfill配合使用,因此它可以很容易地部署在旧版浏览器中。

请随时看一看,并希望有所贡献!