将对象同步到更改的参数

时间:2014-08-21 18:49:22

标签: javascript

我想将Object的参数绑定到另一个Object,因此只要另一个更新,它们就会更新。

Object1 =
  x: 1

Object2 =
  x: Object1.x
  y: 0

以便Object1.x = 2;更新Object2。 (反之亦然)

我该如何有效地做到这一点?我可以使用.watch并在每次更改时更新另一个,但我怀疑这是一个聪明的解决方案。我错过了什么吗?

2 个答案:

答案 0 :(得分:2)

根据必须运行的环境,getter可能是一个合适的解决方案:

Object.defineProperty(Object2, 'x', {
   get: function() {
     return Object1.x;
   },
   enumerable: true
});

您可能还想定义一个setter来同步更改。

答案 1 :(得分:1)

您需要实现观察者/可观察模式。

  

我可以使用.watch并在每次更改时更新另一个,但我   怀疑这是一个聪明的解决方案

如果有变化,您如何通知其他部分?为什么不是智能解决方案?这只是解决方案!

检查此代码清单,我向您展示了一个可能的对象实现,这些对象能够监听其他对象的更改,从而创建基础ObservableObject原型(also available in JSFiddle!)

var ObservableObject = function () {
    this._handlers = [];
    this._disablePropertyChangeNotification = false;
};

ObservableObject.prototype = {
    get disablePropertyChangeNotification() {
        return this._disablePropertyChangeNotification;
    },

    set disablePropertyChangeNotification(value) {
        this._disablePropertyChangeNotification = value;
    },

    listenPropertyChange: function (handler) {
        this._handlers.push(handler);
    },

    notifyPropertyChange: function (propertyName) {
        if (!this.disablePropertyChangeNotification) {
            this._handlers.forEach(function (handler) {
                handler(propertyName);
            });
        }
    },
};

var A = function () {};
A.prototype = new ObservableObject();

Object.defineProperty(A.prototype, "name", {
    get: function () {
        return this._name;
    },
    set: function (value) {
        this._name = value;
        this.notifyPropertyChange("name");
    }
});

var B = function () {};
B.prototype = new ObservableObject();

Object.defineProperty(B.prototype, "name", {
    get: function () {
        return this._name;
    },
    set: function (value) {
        this._name = value;
        this.notifyPropertyChange("name");
    }
});

var someObjectA = new A();
var someObjectB = new B();

someObjectA.listenPropertyChange(function (propertyName) {
    // This will prevent an infinite loop where 
    // property from A is set by B and viceversa
    someObjectA.disablePropertyChangeNotification = true;
    someObjectB[propertyName] = someObjectA[propertyName];
    someObjectA.disablePropertyChangeNotification = false;
});

someObjectB.listenPropertyChange(function (propertyName) {
    // This will prevent an infinite loop where 
    // property from A is set by B and viceversa
    someObjectB.disablePropertyChangeNotification = true;
    someObjectA[propertyName] = someObjectB[propertyName];
    someObjectB.disablePropertyChangeNotification = false;
});

// We set name on A instance, and we print B instance name value
someObjectA.name = "hello world";
$(document.body).append("<p>someObjectB.name: " + someObjectB.name + "</p>");

// We set name on B instance, and we print A instance name value
someObjectB.name = "hello world changed";
$(document.body).append("<p>someObjectA.name: " + someObjectA.name + "</p>");