1. 程式人生 > >Angular的地址監聽與JS陣列引用傳遞方式帶來的衝突

Angular的地址監聽與JS陣列引用傳遞方式帶來的衝突

業務需求:在對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指向的地址 又返回了所需要的值 還能在效能上做到優化 是一種不錯的做法