角度表并不总是有效

时间:2016-08-24 07:51:31

标签: javascript angularjs

我的控制器和手表中有一些功能可以隐藏和显示我页面上的一些元素。

我最初创建了一个对象:

$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);
    }
})

问题是手表并不总是被触发。使用&#39; inverseSelection&#39;和&#39; deselectAll&#39;功能始终被触发,但在使用&{39; selectAll&#39;后不会被触发。和&#39; selectItem&#39; (选择一对一的项目),但我没有看到我在selectedItems数组中推送条目的方式有任何不同。

有人可以帮助我吗?

3 个答案:

答案 0 :(得分:5)

详细说明你提到的两个函数发生的原因:在inverseSelectiondeselectAll函数中初始化一个新数组。

$scope.selectedItems = [];

默认情况下,$scope.$watch仅比较对象引用,即“它是否仍然是同一个对象”。它并不关心实际内容。这就是为什么在初始化一个新的空阵列时手表会激活的原因。在其他函数中,您修改已存在的数组,因此引用是相同的。对于手表来说,它是同一个物体,所以它不会发射。

正如其他人已经提到的,有两种方法可以解决它。

  1. $ scope。$ watch with objectEquality === true
  2. $scope.$watch的第三个参数告诉angular比较对象的内容:

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

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

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

    1. $范围。$ watchCollection
    2. 在你的情况下,这将是更好的解决方案,因为它只是“浅看”对象。这意味着它适用于数组,但不适用于嵌套对象。对于您的数组,性能优于使用$scope.$watch objectEquality的<{1}}。

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

      对于数组,这意味着要观察数组项;对于对象图,这意味着要观察属性

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

答案 1 :(得分:3)

您正在对数组(浅观察者)进行简单监视,因此只有在数组reference发生变化时才会触发。因此,要让你的观察者在数组上进行推送操作。您可以使用$watchCollectionpush&amp;在removal数组元素上。

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

答案 2 :(得分:2)

您可以使用&#34; $ watchCollection&#34;或$ watch,最终参数为true。

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