Angular的地址監聽與JS陣列引用傳遞方式帶來的衝突
阿新 • • 發佈:2019-01-26
業務需求:在對checkbox的選擇後,希望將選擇到的資料列印在input框中。
程式碼實現過程:
<input type="text" ng-model="test">
<input type="button" ng-click="click()">
錯誤做法:
$scope.test = [0,1];
$scope.click = function(){
// $scope.test[2] = 2;
// $scope.test.push(2);
console.log($scope.test)
}
使用直接對陣列的屬性賦值或者push資料這兩種方法 列印$scope.test的值確實為[0,1,2] 但是文字框中仍然顯示0,1
開始以為是因為髒檢查機制的監聽問題 使用了$scope.$apply() 但是報錯提示髒檢查機制已經在運行了
這是因為在JS中陣列的傳遞方式為引用傳遞 而Angular中的監聽模式為地址監聽 直接改變陣列的值 陣列的地址並沒有發生改變 所以髒檢查機制不起效了。
正確做法:
(1)
$scope.test = [0,1];
$scope.click = function(){
var test = $scope.test;
$scope.test = [];
for(var i =0;i<test.length;i++){
$scope.test[i] = test[i];
}
console.log($scope.test)
}
這種做法是new了一個數組 將原來的陣列直接賦值到新陣列上 再將原陣列的地址指向一個空的陣列 然後遍歷用來儲存值的陣列 將值一個一個存入指向的新地址
但是這種做法會遍歷整個陣列 在效能上不建議使用
(2)
$scope.test = [0,1];
$scope.click = function(){
$scope.test = $scope.test.concat("2");
console.log($scope.test)
}
這種做法是用了JS的concat函式 將兩個陣列的值拼接在一起 返回一個新的陣列 這樣既改變了$scope.test指向的地址 又返回了所需要的值 還能在效能上做到優化 是一種不錯的做法