简体   繁体   中英

Scope not updating UI inside the success function of http.get

I want to integrate the same high chart as in this link with Restful API using the $http.get , it doesn't work because of the $scope.pieData is in the success function:

app.directive('hcPieChart', function () {
                return {
                    restrict: 'E',
                    template: '<div></div>',
                    scope: {
                        title: '@',
                        data: '='
                    },
                    link: function (scope, element) {
                        Highcharts.chart(element[0], {
                            chart: {
                                type: 'pie'
                            },
                            title: {
                                text: scope.title
                            },
                            plotOptions: {
                                pie: {
                                    allowPointSelect: true,
                                    cursor: 'pointer',
                                    dataLabels: {
                                        enabled: true,
                                        format: '<b>{point.name}</b>: {point.percentage:.1f} %'
                                    }
                                }
                            },
                            series: [{
                                data: scope.data
                            }]
                        });
                    }
                };
            })

app.controller('myCtrl', function($scope, $http) {

   $http({
              method: 'Get',
              url: 'http://localhost:2195/api/charts',    
          }).success(function(data, status , header, config) {

                // Sample data for pie chart   
                        $scope.pieData = [
                        {
                            name: "Sent SMSs",
                            selected: true,
                            y:  data[0].sentSMS
                        }, 
                        {
                            name: "Not Sent",
                            y: data[0].notSentSMS,
                            sliced: true,

                        }, 
                        {
                            name: "Delivered",
                            y: data[0].deliveredSMS
                        },
                        {
                            name: "Not Delivered",
                            y: data[0].notDeliveredSMS,

                            selected: false
                        }
                    ];          
          }                         

}); // End of Controller               

Here is the JSFiddle link (It will not work, because of the service link).

Anyone could help please.

Jimmy is right, your problem is the chart renders and after that the success function get the response

to prevent that you have to create flag and use ng-if, so the html will be like that

<hc-pie-chart  ng-if="flag" data = "pieData" title="Manual Campaigns" >Placeholder for Manual Campaigns pie chart</hc-pie-chart>

and the JS will be like that:-

$scope.flag = false;   

          $http.get("http://localhost:2195/api/charts")
              .then(function(response) {
                console.log(response);                  

                  $scope.pieData = [
                        {
                            name: "Sent SMSs",
                            selected: true,                            
                            y : response.data[0].sentSMS

                        }, 
                        {
                            name: "Not Sent",
                            y: response.data[0].notSentSMS,
                            sliced: true,

                        }, 
                        {
                            name: "Delivered",
                            y:response.data[0].delivered
                        },
                        {
                            name: "Not Delivered",
                            y: response.data[0].notDelivered,

                            selected: false
                        }
                    ]

                    console.log($scope.pieData);
                    $scope.flag = true;  //set the flag equal true to show it

              });

I've edited your fiddle like so:

Controller

app.controller('myCtrl', function($scope, $http) {

  //Should live in service;
  var getData = function() {
    return $http.get('http://localhost:2195/api/charts')
      .then(function(response) {
        return response.data;
      });
  };

  getData().then(function(data) {

    $scope.pieData = [{
      name: "Sent SMSs",
      selected: true,
      y: response.data[0].autoSent

    }, {
      name: "Not Sent",
      y: response.data[0].notSent,
      sliced: true,

    }, {
      name: "Delivered",
      y: response.data[0].delivered
    }, {
      name: "Not Delivered",
      y: response.data[0].notDelivered,

      selected: false
    }];    

  });

}); // End of Controller

Directive

app.directive('hcPieChart', function() {
  return {
    restrict: 'E',
    template: '<div></div>',
    scope: {
      title: '@',
      data: '='
    },
    link: function(scope, element) {
      //Using a watch ensures that we can always access
      // data in the link function
      scope.$watch('data', function(newValue) {
        Highcharts.chart(element[0], {
          chart: {
            type: 'pie'
          },
          title: {
            text: scope.title
          },
          plotOptions: {
            pie: {
              allowPointSelect: true,
              cursor: 'pointer',
              dataLabels: {
                enabled: true,
                format: '<b>{point.name}</b>: {point.percentage:.1f} %'
              }
            }
          },
          series: [{
            data: newValue
          }]
        });
      });
    }
  };
})

Template

<div class="row" ng-if="pieData">

  <div class="col-md-6">
    <hc-pie-chart title="Manual Campaigns" data="pieData">Placeholder for Manual Campaigns pie chart</hc-pie-chart>
  </div>

  <div class="col-md-6">
    <hc-pie-chart title="Auto Campaigns">Placeholder for Auto Campaigns pie chart</hc-pie-chart>
  </div>

</div>

Note that a lot of this goes against best practices. Angular has moved on a lot since 1.1.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM