我的可观察模式有什么问题?

时间:2014-08-12 20:48:10

标签: javascript

我正在测试javascript中的可观察模式。我在数组中的回调似乎永远不会执行。我的语法出了什么问题?

<script type="text/javascript">


    var Book = function (value) {

        var onChanging = [];
        this.name = function () {

            for (var i = 0; i < onChanging.length; i++) {
                onChanging[i]();
            }

            return value;
        }

        this.addTest = function (fn) {
            onChanging.push(fn);
        }

    }

    var b = new Book(13);
    b.addTest(function () { console.log("executing");  return true; }); 
    b.name = 15;
</script>

3 个答案:

答案 0 :(得分:0)

从上面的代码中看起来你需要调用你的函数名而不是分配一个类似的值:

var b = new Book(13);
b.addTest(function () { console.log("executing");  return true; }); 
b.name(); //<-- Before b.name = 15

答案 1 :(得分:0)

设置b.name = 15并不执行该函数,它只会覆盖b.name的值。

您可以使用getter和setter来响应不断变化的值。 See John Resig's blog postMDN reference

我编辑了您的代码以使用它们:

var Book = function (value) {

     this.onChanging = [];
     this._name = "";    
 }

 Book.prototype = {
     addTest: function (fn) {
         this.onChanging.push(fn);
     },
     get name() {
         return this._name;
     },
     set name(val) {
         for (var i = 0; i < this.onChanging.length; i++) {
             this.onChanging[i](val);
         }
         this._name = val;
     }
 };

 var b = new Book(13);
 b.addTest(function (val) {
     console.log("executing", val);
     return true;
 });
 b.name = 15;
 b.name = 17;

<强> working demo

答案 2 :(得分:0)

您还可以创建一个更通用的解决方案,可以适用于所有属性,而无需定义getter和setter,很多框架都使用这种方法。

Book = function () {
     this._events = [];
     this._rawdata = {};    
}

Book.prototype = {
     bind: function (fn) {
     this._events.push(fn);
},

// pass the property, and it returns its value, pass the value and it sets it!

attr: function (property, val) {
     if (typeof val === "undefined") return this._rawdata[property];
     this._rawdata[property] = val; 
     for (var i = 0; i < this._events.length; i++)

         // we pass out the val and the property
         this._events[i](val, property);
     }
 };

b = new Book();

b.bind(function (val) {
     console.log("executing", val);
     return true;
});

b.attr("name","The Hobbit");
b.attr("SKU" ,1700109393901);

console.log(b.attr("name")); // --> The Hobbit

http://jsfiddle.net/wv4ch6as/

当然,您可能希望更改绑定器,以便绑定到属性而不是绑定所有属性的属性,但我认为这可以实现。