2014-03-19 91 views
0

我正在嘗試製作一個角度範圍的對象,以響應其屬性的更改。這是預期的行爲:回調的範圍界定問題

x = new Scope('a', 'b'); 

x.data = { 
    name: 'Jim', 
    age : 19 
} 

x.$init(); 

x.$digest(); 

x.data.name = 'Bob'; 
x.$digest(); 
// name has been changed from "Jim" to "Bob" 

x.data.age = 200; 
x.$digest(); 

// age has been changed from "19" to "200" 

年齡鍵現在工作正常。但名字沒有。我懷疑這是在下面的功能與範圍有關:

Scope.prototype.$init = function() { 
    $$ = this; 
    $$.keys = Object.keys($$.data); 

    for(var i=0; i<$$.keys.length; i++) { 
    var key = $$.keys[i]; 

    $$.$watch(
     function(scope) { return scope.data[key] }, 
     function(newValue, oldValue, scope) { 
     if(newValue) { 
      console.log ('%s has been changed from "%s" to "%s"',key,oldValue, newValue) 
     } 
     } 
    ) 
    } 
} 

的問題似乎經過var key成這樣:function(scope) { return scope.data[key] },下面是使用其他兩個函數:

Scope.prototype.$watch = function(watchFunction, listenerFunction) { 
    var watcher = { 
    watchFunction: watchFunction, 
    listenerFunction: listenerFunction 
    } 

    this.watchers.unshift(watcher) 
} 

Scope.prototype.$digest = function() { 
    var length = this.watchers.length; 
    var watcher, newValue, oldValue 

    while(length--) { 
    watcher = this.watchers[length]; 
    newValue = watcher.watchFunction(this); 
    oldValue = watcher.last; 

    if(newValue !== oldValue) { 
     watcher.last = newValue; 
     watcher.listenerFunction(newValue, oldValue, this); 
    } 
    } 
} 

有沒有人有任何想法如何解決這個功能?如果我在控制檯中初始化監視器,它可以很好地工作,但我希望它自動執行,所以每次定義一個新變量時都不必定義一個監視器。

+1

的可能重複的[使用Javascript閉合環內 - 簡單的實際例子](http://stackoverflow.com/questions/ 750486/javascript-closure-inside-loops-simple-practical-example) – elclanrs

+0

謝謝,幫助! – andy

回答

0

找到了解決方案。該方法是使用這樣的:

Scope.prototype.$createWatcher = function(key) { 
    return function(scope) { return scope.data[key] } 
} 

然後在init函數:

$$.$watch(
    $$.$createWatcher(key), 
    function(newValue, oldValue, scope) { 
    if(newValue) { 
     console.log ('has been changed from "%s" to "%s"',oldValue, newValue) 
    } 
    } 
)