2016-08-24 38 views
3

我有一些功能在我的控制器和一个手表,隐藏和显示我的网页上的一些元素。角度手表并不总是工作

我最初创建的对象:

$scope.selectedItems = []; 

使用某些功能时,我可以选择连接取消选择:

$scope.selectAllItems = function(items){ 
     for(var i =0; i < items.length; i++){ 
      items[i].selected = true; 
      $scope.selectedItems.push(items[i]._id); 
     } 
    } 

$scope.deselectAllItems = function(items){ 
    for(var i=0; i<items.length; i++){ 
     items[i].selected = false; 
     $scope.selectedItems = []; 
    } 
} 

$scope.inverseAllItems = function(items){ 
    $scope.selectedItems = []; 
    for(var i=0; i<items.length; i++){ 
     items[i].selected = items[i].selected ? false : true; 
     if(items[i].selected) 
      $scope.selectedItems.push(items[i]._id); 
    } 
} 

$scope.selectItem = function(item){ 
    console.log(item.selected); 
    if(item.selected){ 
     console.log(item._id); 
     $scope.selectedItems.push(item._id); 
    }else{ 
     console.log("hier2"); 
     if($scope.selectedItems.indexOf(item._id)) 
      $scope.selectedItems.splice($scope.selectedItems.indexOf(item._id),1) 
    } 
} 

而且在$scope.selectedItems

$scope.$watch("selectedItems", function handleSelectedItemsChange(newValue, oldValue){ 
    console.log("$scope.selectedItems.length", $scope.selectedItems.length); 
    if($scope.selectedItems.length > 1){ 
     $scope.multipleSelect = true; 

     $('.itemStatus').toggleClass('hidden', true); 

    }else{ 
     $scope.multipleSelect = false; 
     $('.itemStatus').toggleClass('hidden', false); 
    } 
}) 

手表的问题是,手表并不总是被触发。在使用'inverseSelection'和'deselectAll'功能后,它始终被触发,但在使用'selectAll'和'selectItem'(一个选择项目)后不会被触发,但我没有看到任何差异我推入selectedItems阵列中的条目。

有人可以帮我吗?

+2

作为一个数组,你应该使用'$ watchCollection' –

+0

aaah。简单但这确实是解决方案。谢谢! – NVO

+0

@PankajParkar你可以做出答案。 – Alok

回答

5

更详细地说明了一下为什么它是在你提到的两个功能发生的原因是:在inverseSelectiondeselectAll函数初始化一个新的数组。

$scope.selectedItems = []; 

缺省情况下,只有$scope.$watch比较对象引用,即,“是它仍然是相同的对象”。它不关心实际的内容。这就是为什么当您初始化一个新的空阵列时手表会触发。在其他函数中,你修改一个已经存在的数组,所以引用是相同的。对于手表来说,它是同一个物体,所以它不会发射。

正如其他人已经提到有两种方法来解决它。 。

  1. $ $范围与objectEquality看===真正

$scope.$watch第三个参数告诉角度为对象的内容进行比较:

$scope.$watch("selectedItems", function handleSelectedItemsChange(newValue, oldValue){ 
    ... 
}, true) 

当objectEquality == true,watchExpression的不等式根据angular.equals函数确定

https://docs.angularjs.org/api/ng/type/%24rootScope.Scope#%24watch

  • $范围。$ watchCollection
  • 在你的情况,这将是因为只有它 “浅手表” 更好的解决方案的目的。这意味着它对数组很好,但不适用于嵌套对象。对于您的阵列,性能要优于使用$scope.$watchobjectEquality

    $scope.$watchCollection("selectedItems", function handleSelectedItemsChange(newValue, oldValue){ 
        ... 
    }) 
    

    为阵列,这意味着看着数组项;为对象映射,这意味着看属性

    https://docs.angularjs.org/api/ng/type/%24rootScope.Scope#%24watchCollection

    2

    您可以使用“$ watchCollection”或$ watch并且最终参数为true。

    angular.$watch('collection', function() {}, true);

    3

    你保持在阵列(浅守望者)一个简单的手表,所以它只会得到火灾时的阵列reference得到改变。所以要让你的观察者在阵列上按下操作。您可以使用$watchCollection,它将在push &上的数组元素的removal上触发。

    $scope.$watchCollection("selectedItems", ......)