admin管理员组

文章数量:1394759

I'm going to get some data from server using $http and JSON response. $http.get() are called after route change. But template are changed before data is downloaded. My goal is:

  • User press a hyperlink in menu, that changes a route,
  • Shows Loading Spinner (DOM Element is in another controller which is on page everytime)
  • Initializing $scope.init() (via ng-init="init()") in controller which is in my new template, this also initializing get data from server
  • Data are downloaded, now I can hide spinner and change visible template

How can I do this? My App looks for example:

Javascript:

var myApp = angular.module('myApp', []);

myApp.controller('MyCtrl', function($scope, $http) {
    $scope.init = function() {
       $http({method: 'GET', url: '/'}).success(function(data) {
           console.log(data);
               $scope.ip = data.ip;
           });
    }
});

myApp.config(function($routeProvider) {

    $routeProvider.when('/link', {
        controller: 'MyCtrl',
        templateUrl: 'embeded.tpl.html'
    });
});

HTML:

<script type="text/ng-template" id="embeded.tpl.html">
    <div ng-controller="MyCtrl" ng-init="init()">
    Your IP Address is: {{ip}}
    </div>
</script>

<div>

    <ul>
        <li><a href="#/link">change route</a></li>
    </ul>

    <div ng-view></div>
</div>

I'm going to get some data from server using $http and JSON response. $http.get() are called after route change. But template are changed before data is downloaded. My goal is:

  • User press a hyperlink in menu, that changes a route,
  • Shows Loading Spinner (DOM Element is in another controller which is on page everytime)
  • Initializing $scope.init() (via ng-init="init()") in controller which is in my new template, this also initializing get data from server
  • Data are downloaded, now I can hide spinner and change visible template

How can I do this? My App looks for example:

Javascript:

var myApp = angular.module('myApp', []);

myApp.controller('MyCtrl', function($scope, $http) {
    $scope.init = function() {
       $http({method: 'GET', url: 'http://ip.jsontest./'}).success(function(data) {
           console.log(data);
               $scope.ip = data.ip;
           });
    }
});

myApp.config(function($routeProvider) {

    $routeProvider.when('/link', {
        controller: 'MyCtrl',
        templateUrl: 'embeded.tpl.html'
    });
});

HTML:

<script type="text/ng-template" id="embeded.tpl.html">
    <div ng-controller="MyCtrl" ng-init="init()">
    Your IP Address is: {{ip}}
    </div>
</script>

<div>

    <ul>
        <li><a href="#/link">change route</a></li>
    </ul>

    <div ng-view></div>
</div>
Share Improve this question asked Dec 21, 2013 at 15:44 SiperSiper 1,1951 gold badge14 silver badges40 bronze badges 4
  • Have you looked at this thread? stackoverflow./questions/17144180/… – codingjoe Commented Dec 21, 2013 at 15:47
  • Yes, but that's not what I need. – Siper Commented Dec 21, 2013 at 15:52
  • Why don't you simply send the http request when the controller is constructed, and have a view like <div ng-show="ip">...</div> (i.e. it doesn't show anything until the data is received)? – JB Nizet Commented Dec 21, 2013 at 16:01
  • I would rather change the page structure. I don't think ng-view is the best solution for you. Maybe you could work with with ngInclude to change just what you need to update in your page. Have the url change a significant role in your application logic? Do you use some url parameter? – pasine Commented Dec 21, 2013 at 17:32
Add a ment  | 

2 Answers 2

Reset to default 6

You need to resolve data before routing happens, thus, move your $http to config section.

This is good tutorial for that, http://www.thinkster.io/pick/6cmY50Dsyf/angularjs-resolve-conventions

This is config part.

 $routeProvider.when('/link', {
    controller: 'MyCtrl',
    templateUrl: 'embeded.tpl.html',
    resolve: {
      data: function ($q, $http) {
        var deferred = $q.defer();
        $http({method: 'GET', url: 'http://ip.jsontest./'}).then(function(data) {
          deferred.resolve(data);
        });
        return deferred.promise;
      }
    }
 }

and this is controller part

//`data` is injected from routeProvider after resolved
myApp.controller('MyCtrl', function($scope, $http, data) { 
  $scope.ip = data.ip
});

I think promise in AngularJS is very important concept for any async. processing. You need to use this technique every time you have callback.

I will not do it all for you, however I will point you in the right direction.

First you need the ngRoute module.

var myApp = angular.module('myApp', ['ngRoute']);

And the JS file:

<script src="//ajax.googleapis./ajax/libs/angularjs/1.2.5/angular-route.js"></script>

Now you routes will be working and you do not need to call a special init function in your controller since they get instanciated on every route change when used with ng-view.

For the spinner, you could add some interceptors to all ajax requests using the $httpProvider. Inside the interceptors you could emit some events on the $rootScope and listen to then in a specialed custom attribute directive e.g. spinner where the magic would occur ;)

本文标签: javascriptChange ngview after get data in AngularJSStack Overflow