0

我使用 ECMA7Object.observe或 MozillaObject.watch而不是eventEmitternode 进行数据绑定。

对于Object.observe,我找不到任何关于 android 浏览器兼容性的实现。他们基本上必须使用 setTimeout 轮询,所以我放弃了。

相反,Object.watch可以在没有任何轮询的情况下使用 Chrome 库和本机 Firefox 等运行。

我找到的代码是

if (!Object.prototype.watch)
{
    Object.defineProperty(Object.prototype, "watch",
    {
        enumerable: false,
        configurable: true,
        writable: false,
        value: function(prop, handler)
        {
            var
            oldval = this[prop],
                newval = oldval,
                getter = function()
                {
                    return newval;
                },
                setter = function(val)
                {
                    oldval = newval;
                    return newval = handler.call(this, prop, oldval, val);
                };

            if (delete this[prop])
            { // can't watch constants
                Object.defineProperty(this, prop,
                {
                    get: getter,
                    set: setter,
                    enumerable: true,
                    configurable: true
                });
            }
        }
    });
}

// object.unwatch
if (!Object.prototype.unwatch)
{
    Object.defineProperty(Object.prototype, "unwatch",
    {
        enumerable: false,
        configurable: true,
        writable: false,
        value: function(prop)
        {
            var val = this[prop];
            delete this[prop]; // remove accessors
            this[prop] = val;
        }
    });
}

这适用于

obj.watch('foo',
      function(id, oldval, newval)
      {
        //..........

        return newval;
      });

但是,出现了一个大问题,就是当我在各个地方实现多个watch时,只有第一个obj.watch被触发,其余的都不会触发。

原因很明显。

在第一次触发时,其余的 obj.watch 会自动设置为监视更改的值。

测试代码:

var obj = {
      foo: 5
    };

obj.watch('foo',
  function(id, oldval, newval)
  {
    alert(newval);

    return newval;
  });

obj.watch('foo',
  function(id, oldval, newval)
  {
    alert(newval);

    return newval;
  });

obj.foo = 7;

结果:没有错误,但只发出一次警报。

实际上,我试图找到允许为同一对象实例/属性触发多个监视块的替代库/机制。

同样,我将避免使用 eventEmitter 模式,而是避免使用观察者模式。你有什么主意吗?谢谢。

4

3 回答 3

0

自答。

还不确定,但一种方法是使用
melanke/Watch.JS/ https://github.com/melanke/Watch.JS/ 我早就知道了。

它确实有效:

http://jsfiddle.net/NbJuh/62/

//defining our object no matter which way we want
var obj = {
    foo: "initial value of attr1" 
};

//defining a 'watcher' for an attribute
watch(obj, "foo", function(){
    alert("foo changes!");
});
watch(obj, "foo", function(){
    alert("foo changes!");
});
//when changing the attribute its watcher will be invoked
obj.foo = "other value";
于 2014-06-07T05:00:33.507 回答
0

一个制作精良的Object.defineProperty应该做的伎俩。

更现代的方法是使用带有new Proxy(object, {...}).

于 2016-12-02T22:18:48.647 回答
0

这是非常接近您要查找的内容的小库

https://github.com/imolus/js-object-watch

于 2016-07-05T21:51:13.260 回答