最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - AngularJS, resolve data before showing view - Stack Overflow

programmeradmin4浏览0评论

This subject has been already asked but I couldn't figure out what to do in my case.

Using AngularJS 1.0.5:

Before showing the view "login", I want to get some data and delay the view rendering while the data isn't loaded from an AJAX request.

Here is the main code. Is it the good way?

angular.module('tfc', ['tfc.config', 'tfc.services', 'tfc.controllers']).config([
 '$routeProvider', '$locationProvider', '$httpProvider',
 function($routeProvider, $locationProvider, $httpProvider) {
  $routeProvider.when('/login', {
    templateUrl: 'views/login.html',
    controller: "RouteController",
    resolve: {
      data: function(DataResolver) {
        return DataResolver();
      }
    }
  });
}
]);

module_services = angular.module("tfc.services", []);

module_services.factory("DataResolver", [
 "$route", function($route) {
  console.log("init");
  return function() {
    // Tabletop is a lib to get data from google spreadsheets
    // basically this is an ajax request
    return Tabletop.init({
      key: "xxxxx",
      callback: function(data, tabletop) {
        console.log("[Debug][DataResolver] Data received!");
        return data;
      }
    });
  };
 }
]);

This subject has been already asked but I couldn't figure out what to do in my case.

Using AngularJS 1.0.5:

Before showing the view "login", I want to get some data and delay the view rendering while the data isn't loaded from an AJAX request.

Here is the main code. Is it the good way?

angular.module('tfc', ['tfc.config', 'tfc.services', 'tfc.controllers']).config([
 '$routeProvider', '$locationProvider', '$httpProvider',
 function($routeProvider, $locationProvider, $httpProvider) {
  $routeProvider.when('/login', {
    templateUrl: 'views/login.html',
    controller: "RouteController",
    resolve: {
      data: function(DataResolver) {
        return DataResolver();
      }
    }
  });
}
]);

module_services = angular.module("tfc.services", []);

module_services.factory("DataResolver", [
 "$route", function($route) {
  console.log("init");
  return function() {
    // Tabletop is a lib to get data from google spreadsheets
    // basically this is an ajax request
    return Tabletop.init({
      key: "xxxxx",
      callback: function(data, tabletop) {
        console.log("[Debug][DataResolver] Data received!");
        return data;
      }
    });
  };
 }
]);
Share Improve this question asked Mar 6, 2013 at 9:30 LaurentLaurent 9873 gold badges13 silver badges27 bronze badges 5
  • 2 Maybe answer from AngularJS' creator can helps you: stackoverflow./a/11972028/449162 – L42y Commented Mar 6, 2013 at 13:22
  • You could also assign the result of the AJAX request to something in your $scope and just use ng-show in the HTML. – boxed Commented Mar 6, 2013 at 16:00
  • 1 This is a pretty solid way to do it. it's way better than using ng-show or ng-hide because in your controller, you'll have your data already and can write more synchronous code. That said, this more suits for a code-review site than SO, because you don't have a problem but looking for improvements in your code. – Umur Kontacı Commented Jul 31, 2014 at 23:58
  • @L42y Funny that Misko also asked that question. – Shomz Commented Aug 1, 2014 at 0:02
  • possible duplicate of Delaying AngularJS route change until model loaded to prevent flicker – ivarni Commented Aug 4, 2014 at 10:48
Add a ment  | 

2 Answers 2

Reset to default 1

The point of AngularJS is that you can load up the templates and everything and then wait for the data to load, it's meant to be asynchronous.

Your view should be using ng-hide, ng-show to check the scope of the controller so that when the data in the scope is updated, the view will display. You can also display a spinner so that the user doesn't feel like the website has crashed.

Answering the question, the way you are loading data explicitly before the view is rendered seems right. Remember that it may not give the best experience as there will be some time to resolve that, maybe giving an impression that your app stopped for some moments.

See an example from John Pappa's blog to load some data before the route is resolved using angular's default router:

// route-config.js
angular
    .module('app')
    .config(config);

function config($routeProvider) {
    $routeProvider
        .when('/avengers', {
            templateUrl: 'avengers.html',
            controller: 'Avengers',
            controllerAs: 'vm',
            resolve: {
                moviesPrepService: function(movieService) {
                    return movieService.getMovies();
                }
            }
        });
}

// avengers.js
angular
    .module('app')
    .controller('Avengers', Avengers);

Avengers.$inject = ['moviesPrepService'];
function Avengers(moviesPrepService) {
    var vm = this;
    vm.movies = moviesPrepService.movies;
}

You basically use the resolve parameters on the route, so that routeProvider waits for all promises to be resolved before instantiating the controller. See the docs for extra info.

发布评论

评论列表(0)

  1. 暂无评论