2016-02-25 3 views
5

Я использую два $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 и угловых диаграмм) читать данные из них. Я поместил диаграммы в пользовательские директивы, которые получают данные из атрибута, и они работают правильно.

Проблема заключается в том, что я хочу, чтобы создать еще одну таблицу, которая читает другой объект, равный их, но вычислил его данные в этом методе:

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 не делает, так как эти часы просто не работают.

Я делаю что-то неправильно в этих двух часах?

+0

в 'console.log ("СФЕРА:")', является '$ scope.beneficios.data' быть распечатаны с его обновленной стоимостью? – Rhumborl

+3

Возможный дубликат [$ watch не запускается при изменении массива] (http: // stackoverflow.com/questions/15363259/watch-not-being-triggered-on-array-change) – mido

ответ

5

Проблема заключается в том, что вы смотрите верхний уровень gastos и ganancias объектов. Есть два возможных проблем с этим:

  1. Как docs for $watch сказать, по умолчанию, нормальное неравенство JavaScript используется для определения того, является ли объект изменился (x !== y). Поскольку объект сам по себе является одним и тем же объектом, вы просто меняете данные в пределах, это всегда будет правдой, поэтому $watch не уволен.

  2. Вы можете обойти 1. установив флаг objectEquality в значение true ($scope.$watch('x', function(){}, true)). Это затем делает глубокое сравнение и должно выявлять различия в массиве data. Однако это значительно повышает производительность.

Как вы используете только data массив в каждом объекте, вы можете просто использовать $scope.$watchCollection на gastos.data. Это чище и быстрее.

Здесь рабочий фрагмент кода демонстрирует это:

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>

3

Используйте $watchCollection вместо $watch, чтобы посмотреть коллекцию.

Или вы можете также наблюдать, как это:

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

Спасибо! Оба работают, но только в том случае, если я нацелен на гастасы. Data и ganancias.data. Что я должен использовать, $ watchCollection и поместить часы для каждого из них или эти простые $ watch? – Zerok

+1

Вы должны использовать '$ watchCollection' вместо этого, потому что он должен быть дешевле, чем глубокие' $ watch'. http://www.bennadel.com/blog/2566-scope-watch-vs-watchcollection-in-angularjs.htm –

+0

Вы можете получить более подробное использование '$ watch' и' $ watchCollection' в http: // stackoverflow .com/а/29189252/2405040. Теперь это зависит от ваших потребностей. –

Смежные вопросы