jquery(或plain js)将change事件绑定到数组中对象的属性

时间:2011-11-15 07:59:14

标签: javascript jquery

我有一个对象数组,这些对象都有一个'isvalid'属性。

有没有办法用JQuery或普通的javascript将代码绑定到该属性的值发生变化的事件?

所以当我有一个包含10个对象的数组时,我想在其中一个对象更改的'isvalid'属性时执行一个函数。

这可能吗?

米歇尔

3 个答案:

答案 0 :(得分:3)

使用属性setter 函数可以使用纯JavaScript。使用ES5语法,如下所示(live example - 适用于Chrome和其他符合ES5标准的浏览器):

// Our constructor function
function Thing() {
}

// Define a "foo" property with a setter and getter
Object.defineProperty(Thing.prototype, "foo", {
  set: function(value) {
    this.fooStorage = value;
    display("Foo was set to '" + value + "'");
  },
  get: function() {
    return this.fooStorage;
  }
});

// Create a `Thing`  
var t = new Thing();

// Set its property
t.foo = "bar";

执行t.foo = "bar";赋值时,将调用setter函数。如果愿意,您可以让setter函数调用回调,以通知您Thing对象已更改。

请注意,上面只是一个例子。它使用fooStorage属性来存储foo的值,这个值不太理想,但很好,很简单。

要以与非ES5 JavaScript引擎兼容的方式执行此操作,您必须依赖Mozilla的一些专有且现已弃用的语法(不能在其他引擎上运行),或者只使用< em>显式 setter函数(live example):

// Our constructor function
function Thing() {
}

// Define a "foo" property with a setter and getter
Thing.prototype.setFoo = function(value) {
  this.fooStorage = value;
  display("Foo was set to '" + value + "'");
};
Thing.prototype.getFoo = function() {
  return this.fooStorage;
};

// Create a `Thing`
var t = new Thing();

// Set the property
t.setFoo("bar");

(再次,这只是一个使用简单方法存储foo值的示例。)

这样做的好处是它几乎可以与任何JavaScript引擎一起使用,而不仅仅是符合ES5的引擎,并且明确设置foo是函数调用,而不仅仅是属性赋值(而使用ES5 setter) / getter语法,设置foo属性的人不知道它是一个函数调用 - 它有上升和缺点。)

这就是你如何捕捉财产变化的事实。然后,这只是允许注册和删除回调以接收更改通知的问题。这些可以通过简单的数组轻松管理。这是一个基于ES5的示例,基于每个对象进行;很明显,你可以用某种分组的方式来做这件事,而不是你想让人们观看的整个对象数组。 (live copy

window.onload = function() {

  // Our constructor function
  function Thing() {
    this.fooHandlers = [];
  }

  // Add a listener for "foo" changes
  Thing.prototype.addFooChangeHandler = function(callback) {
    this.fooHandlers.push(callback);
  };

  // Remove a listener for "foo" changes
  Thing.prototype.removeFooChangeHandler = function(callback) {
    var index;

    index = this.fooHandlers.indexOf(callback);
    if (index >= 0) {
      this.fooHandlers.splice(index, 1);
    }
  };

  // Define a "foo" property with a setter and getter
  Object.defineProperty(Thing.prototype, "foo", {
    set: function(value) {
      var index;

      for (index = 0; index < this.fooHandlers.length; ++index) {
        try {
          // Handler receives a reference to this Thing,
          // foo's old value, and foo's new value.
          this.fooHandlers[index](this, value, this.fooStorage);
        }
        catch (e) {
        }
      }

      this.fooStorage = value;
    },
    get: function() {
      return this.fooStorage;
    }
  });

  // Create a `Thing`
  var t = new Thing();

  // Add a foo change handler
  t.addFooChangeHandler(function(t, newValue, oldValue) {
    display("Handler 1: Foo changed from '" + oldValue + "' to '" + newValue + "'");
  });

  // Add another
  t.addFooChangeHandler(function(t, newValue, oldValue) {
    display("Handler 2: Foo changed from '" + oldValue + "' to '" + newValue + "'");
  });

  // Set the property
  t.foo = "bar";
  t.foo = "boo";

  // === Basic utility functions

  function display(msg) {
    var p = document.createElement('p');
    p.innerHTML = msg;
    document.body.appendChild(p);
  }
};

要在没有ES5 JavaScript引擎的情况下执行此操作,只需设置前面描述的setFoo / getFoo模型,并确保引擎正确支持Array#indexOf(某些引擎没有总之,有些人使用==而不是===等价)或者在Array#indexOf中使用removeFooChangeHandler替换使用简单循环遍历数组寻找回调:

// Remove a listener for "foo" changes
Thing.prototype.removeFooChangeHandler = function(callback) {
  var index;

  for (index = 0; index < this.fooHandlers.length; ++index) {
    if (this.fooHandlers[index] === callback) {
      this.fooHandlers.splice(index, 1);
      break;
    }
  }
};

附注:这些示例中有许多匿名函数。我这样做是为了避免使事情变得复杂,但是I'm not a fan of anonymous functions,我更喜欢函数有名字。有关详细信息,请参阅链接。

答案 1 :(得分:0)

您可以做的一件事是将对象的属性设置为私有,然后仅使用setter更改它们。这样,每次使用setter设置变量时都可以触发事件。这适用于任何环境。

如果你只限于浏览器,你可以使用watch(在这里查看Object.watch() for all browsers?以获得浏览器之间的兼容性)

答案 2 :(得分:0)

看看这个:http://blog.hydroprofessional.com/?p=84

当您进行财产更改时,会通知您