2016-02-25 21 views
5

używam dwóch $watches w moim kontrolera, które mają brać oko na tych dwóch obiektów:

$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"] 
}; 

dwa wykresy (z wtyczek kątowych-Charts.js i wykresów) odczytać z nich dane. Umieściłem wykresy w dyrektywach niestandardowych, które otrzymują dane z atrybutu i działają poprawnie.

Problemem jest to, że chcę, aby utworzyć kolejny wykres, który czyta inny obiekt, który jest równy nich, ale oblicza To dane w tej metodzie:

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

Są to zegarki (próbowałem zarówno oglądanie object i object.data zmienna):

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

To nie działa. Widzisz wszystkie console.logs? Widzę tylko "SCOPE" console.log, raz (nawet nie dwa razy dla ganancias). Kiedy zmieniam dane w niektórych danych wejściowych, które są powiązane z tymi dwoma obiektami, wszystko działa (wykresy są aktualizowane w czasie rzeczywistym), ale wykres beneficios nie, jak również te zegarki po prostu nie działają.

Czy robię coś złego w tych dwóch zegarkach?

+0

w 'console.log (zakres: "")', '$ scope.beneficios.data' ma być wydrukowany z jego zaktualizowaną wartością? – Rhumborl

+3

Możliwy duplikat [$ watch nie jest wyzwalany przy zmianie tablicy] (http: // stackoverflow.com/questions/15363259/watch-not-being-triggered-on-array-change) – mido

Odpowiedz

5

Problemem jest to, że podczas oglądania najwyższego poziomu gastos i ganancias obiektów. Istnieją dwa potencjalne problemy z tym:

  1. Jako docs for $watch powiedzieć, domyślnie normalny nierówność JavaScript jest używana do określenia, czy obiekt został zmieniony (x !== y). Ponieważ sam obiekt jest tym samym obiektem, zmieniasz tylko dane w ciągu, to zawsze będzie prawdziwe, więc $watch nie zostanie wyrzucone.

  2. Możesz obejść 1., ustawiając flagę objectEquality na true ($scope.$watch('x', function(){}, true)). To robi głębokie porównanie i powinno zebrać różnice w tablicy data. Jest to jednak znacznie bardziej wydajne.

Jak jesteś po prostu za pomocą tablicy w każdym obiekcie data, można po prostu użyć $scope.$watchCollection na gastos.data. To jest czystsze i szybsze.

Oto fragment pracy demonstrując w ten sposób:

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

Użyj $watchCollection zamiast $watch, aby obejrzeć kolekcję.

Albo można też oglądać tak:

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

Dziękujemy! Oba działają, ale tylko jeśli celuję w gastos.data i ganancias.data. Którego powinienem użyć, $ watchCollection i umieścić zegarek dla każdego z nich, lub ten prosty zegarek? – Zerok

+1

Zamiast tego powinieneś użyć '$ watchCollection', ponieważ powinien on być tańszy niż głęboki' $ watch'. http://www.bennadel.com/blog/2566-scope-watch-vs-watchcollection-in-angularjs.htm –

+0

Możesz uzyskać bardziej szczegółowe użycie '$ watch' &' $ watchCollection' na http: // stackoverflow .com/a/29189252/2405040. Teraz zależy od twoich potrzeb. –

Powiązane problemy