2016-01-07 51 views
0

我的問題很簡單,但經過很多搜索我找不到答案。有沒有什麼辦法可以看到一個數組的變化,並在添加一個新的元素時觸發一個函數,例如在這個元素被調用。Angular js watchexpression cacth新元素

$ watchExpression在數組中被推入一個新元素時工作正常,但它沒有提供任何有關添加元素的信息。我正在考慮實現一個包含兩個變量的函數,一個是在添加新元素之前包含數組,另一個是包含數組新狀態的變量並對它們進行比較,所以我可以找到添加的元素,但是這個解決方案似乎很不清楚效率低下。有沒有更好的解決方案?

預先

THX我嘗試這樣做:

$scope.names = ['igor', 'matias', 'misko', 'james']; 

$scope.$watchCollection('names', function(newNames, old) { 
    console.log(newNames); 
    console.log(old); 
}); 

$scope.names.push("john"); 

但輸出是這樣的:

[ 「伊戈爾」, 「馬蒂亞斯」, 「MISKO」, 「詹姆斯」 , 「約翰」]

[ 「伊戈爾」, 「馬蒂亞斯」, 「MISKO」, 「詹姆斯」, 「約翰」]

+0

您不能將新名稱用作變量的名稱。編輯:我沒有看到你編輯已經 –

回答

0

您可以使用lodash的_.difference。

https://github.com/rockabox/ng-lodash

$scope.$watch('scopeToWatch', function(newVal, oldVal){ 
var changed; 
changed = lodash.difference(oldVal, newVal); 
console.log(changed); 
}) 

如果你想看看是否被添加或刪除的項目,這樣做:

 $scope.$watch('scopeToWatch', function(newVal, oldVal){ 
    var change; 
    if(newVal.length>oldVal.length){ 
    change = 'added'; 
    } else if(newVal.length<oldVal.length) { 
    change = 'removed'; 
    } else { 
    change = 'none' 
    } 

     var changed; 
     changed = lodash.difference(oldVal, newVal); 
if(change !== 'none'){ 
     console.log(changed+ 'was '+ change); 
} else { 
     console.log('no change'); 

} 
    }) 
+0

Thx你的答案,但我不能適應你的例子,以我的測試案例。我找不到任何有關lodash的文檔。差異功能,所以我很困惑如何使用它。 – JmRag

+0

經過試驗和錯誤,我設法使它工作,但結果與我的一樣。 oldval和newVal都具有相同的值。 – JmRag

0

唯一有效的解決方案,我能想出是覆蓋推送功能對於給定的數組。當然你也可以將它應用於.concat等東西,具體取決於你需要的東西。 當然,您也可以將此重寫過程重構爲更好的代碼風格的函數/服務。這僅僅是用於演示目的:

var x = [1,2,3]; // define the initial array 
x._push = x.push; // "backup" the normal push function 
x.push = function() { 
    x._push(a); // do the normal push 
    console.log ('added: ' + a); // do your magic here... 
}; 

x.push (4); 

我希望這有助於

+0

Thx爲您的答案。你提出的建議適用於我在問題中發佈的示例,但在許多情況下,數組的處理不是來自用戶。所以我對觀察者的解決方案更感興趣。 – JmRag

+0

你是什麼意思的陣列handlng不是從用戶? 當您覆蓋相應的推送功能時,當新條目被推入陣列時,您將始終得到通知。在代碼中數組更改的位置並不重要(即使在調用該數組的.push函數的外部庫中) –

0

與輸出的問題是,瀏覽器控制檯不記錄數組的數組的一個副本,但只是參考異步。 之後當您在控制檯中打開數組時(例如以Google-Chrome的開發者控制檯爲例),它將在檢查時顯示它包含的元素,而不是它在正式記錄時的元素。 你可以做什麼來避免這種情況是記錄數組的副本。 所以問題實際上是console.log函數本身,而不是你的代碼。 嘗試

console.log (old.slice()); 

,而不是

console.log (old); 

這使得因此陣列應記錄你的陣列的副本,是因爲它不會在事後改變。