【问题标题】:Angular $watch not workingAngular $watch 不工作
【发布时间】:2016-06-07 23:52:34
【问题描述】:

我在控制器上使用了两个 $watches,它们应该关注这两个对象:

$scope.gastos = {
    name: "Gastos mensuales",
    data: [0,0,0,0,0,0,0,0,0,0,0,0],
    labels: ["Enero", "Febrero", "Marzo", "Abril", "Mayo",
                "Junio", "Julio", "Agosto", "Septiembre", "Octubre",
                "Noviembre", "Diciembre"]
};

$scope.ganancias = {
    name: "Ganancias mensuales",
    data: [0,0,0,0,0,0,0,0,0,0,0,0],
    labels: ["Enero", "Febrero", "Marzo", "Abril", "Mayo",
                "Junio", "Julio", "Agosto", "Septiembre", "Octubre",
                "Noviembre", "Diciembre"]
};

两个图表(来自 Charts.js 和 angular-charts 插件)从中读取数据。我已将图表放在从属性接收数据的自定义指令中,并且它们工作正常。

问题是,我想创建另一个图表来读取另一个等于这些对象的对象,但在此方法中计算它的数据:

function calcularBeneficios(){
 var data = [];
 for(var i=0;i<12;i++){
    data[i] = $scope.ganancias.data[i] - $scope.gastos.data[i];
 }
    console.log("FUNCTION DATA: "+data);
 return data;
}

这些是手表(我尝试同时查看object 和object.data 变量):

$scope.$watch("gastos", function(){
  $scope.beneficios.data = calcularBeneficios();
  console.log("SCOPE: "+$scope.beneficios.data);
});

$scope.$watch("ganancias", function(){
  $scope.beneficios.data = calcularBeneficios();
  console.log("SCOPE: "+$scope.beneficios.data);
});

这不起作用。你看到所有的console.logs了吗?我只看到一次"SCOPE" console.log(ganancias 甚至没有两次)。当我更改绑定到这两个对象的某些输入中的数据时,一切正常(图表实时更新)但beneficios 图表没有,这些手表也不起作用。

我在这两款手表上做错了吗?

【问题讨论】:

标签: javascript angularjs


【解决方案1】:

使用$watchCollection 而不是$watch 来监视收藏。

或者你也可以这样看:

$scope.$watch("gastos + ganancias", function(){
  $scope.beneficios.data = calcularBeneficios();
  console.log("SCOPE: "+$scope.beneficios.data);
});

【讨论】:

  • 谢谢!两者都有效,但前提是我的目标是 gastos.data 和 ganancias.data。我应该使用哪个,$watchCollection 并为每个人放置一个手表,还是那个简单的 $watch?
  • 你应该改用$watchCollection,因为它应该比深层$watch便宜。 bennadel.com/blog/…
  • 您可以在stackoverflow.com/a/29189252/2405040 获得$watch 和$watchCollection 的更详细用法。现在取决于您的需要。
  • 顺便说一句 $scope.$watchGroup(["gastos", "ganancias"]) 比 $watch("gastos + ganancias") 干净
【解决方案2】:

问题是您正在观看顶级 gastos 和 ganancias 对象。这有两个潜在的问题:

  1. 正如docs for $watch 所说,默认情况下,正常的JavaScript 不等式用于确定对象是否已更改(x !== y)。由于对象本身是同一个对象,您只是在 中更改数据,这始终是正确的,因此不会触发 $watch。

  2. 您可以通过将 objectEquality 标志设置为 true ($scope.$watch('x', function(){}, true)) 来解决 1.然后进行深入比较,并应找出data 数组中的差异。但是,这对性能要求更高。

由于您只是在每个对象中使用data 数组,因此您可以简单地在gastos.data 上使用$scope.$watchCollection。这样更干净、更快捷。

这是一个有效的 sn-p 演示:

angular.module("myApp", []).controller('myCtrl', function($scope) {

  // same code
  function calcularBeneficios() {
    var data = [];
    for (var i = 0; i < 12; i++) {
      data[i] = $scope.ganancias.data[i] - $scope.gastos.data[i];
    }
    console.log("FUNCTION DATA: " + data);
    return data;
  }

  
  $scope.beneficios = {
    name: "Beneficios mensuales",
    data: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
    labels: ["Enero", "Febrero", "Marzo", "Abril", "Mayo",
      "Junio", "Julio", "Agosto", "Septiembre", "Octubre",
      "Noviembre", "Diciembre"
    ]
  };
  
  $scope.gastos = {
    name: "Gastos mensuales",
    data: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
    labels: ["Enero", "Febrero", "Marzo", "Abril", "Mayo",
      "Junio", "Julio", "Agosto", "Septiembre", "Octubre",
      "Noviembre", "Diciembre"
    ]
  };

  $scope.ganancias = {
    name: "Ganancias mensuales",
    data: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
    labels: ["Enero", "Febrero", "Marzo", "Abril", "Mayo",
      "Junio", "Julio", "Agosto", "Septiembre", "Octubre",
      "Noviembre", "Diciembre"
    ]
  };

  // watch the array collection in gastos.data 
  $scope.$watchCollection("gastos.data", function() {
    $scope.beneficios.data = calcularBeneficios();
    console.log("SCOPE: " + $scope.beneficios.data);
  });

  // watch the array collection in ganancias.data 
  $scope.$watchCollection("ganancias.data", function() {
    $scope.beneficios.data = calcularBeneficios();
    console.log("SCOPE: " + $scope.beneficios.data);
  });
  
  
  // testing functions

  $scope.changeGastos = function() {
    $scope.gastos.data[4] = 10;
  }
  
  $scope.changeGanancias = function() {
    $scope.ganancias.data[0] = 40;
  }
})
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.0/angular.min.js"></script>

<div ng-app="myApp" ng-controller="myCtrl">
  <h3>beneficios.data</h3>
  <ul>
    <li ng-repeat="i in beneficios.data track by $index">{{i}}</li>
  </ul>
  <button ng-click="changeGastos()">Change Gastos</button>
  <button ng-click="changeGanancias()">Change Ganancias</button>
</div>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-14
    • 2015-01-20
    • 2016-06-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多