I have an application that is written around the MEAN web stack. I have created an API that depending upon the URL a JSON data set is returned for given weights. This is interconnected with my Mongo database. There are two returned JSON types, one for all weights and another for weights that fall between two dates. Not only am I displaying all of these weights in the first instance on one page(home/index), but I am also displaying by a filtered set(by date) on an independent page. This independent page utilizes both angular-chart.js
and ngDaterangepicker
. These are both Angular directives that are injected into my code.
When a date range is selected a ng-change
function runs (change()
) which grabs a new set of filtered data(by date). This data is then added back into $scope.data
the property, which when changed, should theoretically cause the chart to re-plot. Unfortunately, my application is not watching for new changes to this property inside of a on-change function.
If a timeout is set outside of this function the graph will re-plot. So I am wondering if there is a better way or a different way to solve this problem.
According to the documentation from angular-chart
if there is any change to the value of $scope.data
the chart will re-plot the new values, however anything inside of an on change event listener/function will cause any new values set to $scope.data
to not be bound and cause the graph not to replot the new values. Why is the ng-change
directive so special? Below is my HTML and JavaScript.
=== HTML View ===
<div class="container-fluid"> <h1 class="text-center">Graphs</h1> <div class="container"> <div class="col-sm-12" ng-controller="weights"> <input type="text" ng-change="change()" ng-model="model"/> <input type="daterange" ng-change="change({{myDateRange | json}})" ng-model="myDateRange" /> {{myDateRange | json}} {{data}} </div> <div class="col-sm-12"> <div class="col-sm-2"></div> <div class="col-sm-8 center-block"> <div ng-controller="weights"> <canvas id="line" class="chart chart-line" chart-data="data" chart-labels="labels" chart-legend="true" chart-series="series" chart-click="onClick"> </canvas> </div> </div> <div class="col-sm-2"></div> </div> </div> </div>
=== Angular Controller ===
angular.module('app').controller('weights', ['$scope', 'weightsFactory','$filter','$http', '$timeout', function($scope, weightsFactory, $filter, $http, $timeout){ //need to get weights from /weights //$scope.labels = [1, 2, 3, 4]; $scope.series = ['Weights Over Time']; $http.get('/weights').success(function(data){ //all data var dates = []; var weights = []; $scope.weights = data; angular.forEach(data, function(value, key){ dates.push($filter('date')(value.date, 'MMM dd, yyyy - hh:m:ss a')); weights.push(value.weight); }); $scope.labels = dates; $scope.data = [ weights ]; }); $scope.change = function(data){ //2016-04-08T04:00:00.000Z/2016-04-09T03:59:59.999Z var startTime = '2016-04-08T04:00:00.000Z'; var endTime = '2016-04-09T03:59:59.999Z'; $http.get('/weight/range/'+startTime+'/'+endTime).success(function(response){ $timeout(function() { $scope.data = [['100', '200', '300']]; //this data is being set but is not causing a change on chart.js }, 10); }); }
3 Answers
Answers 1
I wasted 50+ bounty on this question, however it is safe to assume that you can have the same controller in an application, however if you nest two controllers together then yes the application will work, however you will have essentially two different $scope variables in memory. I am not going to remove my error only to prove that if all else fails, look for identical controllers. Be careful with your HTML.
Answers 2
As far as i can see your $scope.change
function resides outside of the weights
controller scope, hence unreachable by ng-change
Answers 3
i would imaging your controller is being loaded twice.
<div ng-controller="weights"> <div class="col-sm-12" ng-controller="weights">
if you were to remove them both and add the controller to the container-fluid div, you should be able to share the state of the controller with the ng-change directive.
<div class="container-fluid" ng-controller="weights"> <h1 class="text-center">Graphs</h1> <div class="container"> <div class="col-sm-12"> <input type="daterange" ng-change="change({{myDateRange | json}})" ng-model="myDateRange" /> {{myDateRange | json}} {{data}} </div> </div> <div class="col-sm-12"> <div class="col-sm-2"></div> <div class="col-sm-8 center-block"> ... <div> <canvas></canvas> </div> </div> <div class="col-sm-2"></div> </div> </div>
0 comments:
Post a Comment