AngularJS,在显示视图之前解析数据

AngularJS, resolve data before showing view

本文关键字:数据 视图 显示 AngularJS      更新时间:2023-09-26

这个问题已经被问过了,但我不知道该怎么做。

使用AngularJS 1.0.5:

在显示视图"login"之前,我想获得一些数据并延迟视图渲染,而数据不是从AJAX请求加载的。

下面是主代码。这是好方法吗?

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

AngularJS的关键是你可以加载模板和所有东西,然后等待数据加载,这意味着它是异步的。

你的视图应该使用ng-hide, ng-show来检查控制器的作用域,这样当作用域中的数据被更新时,视图就会显示出来。你也可以显示一个旋转器,这样用户就不会觉得网站崩溃了。

回答这个问题,在呈现视图之前显式加载数据的方式似乎是正确的。请记住,它可能不会提供最好的体验,因为需要一些时间来解决这个问题,可能会给人留下你的应用程序停止了一段时间的印象。

参见John Pappa博客中的示例,在使用angular的默认路由器解析路由之前加载一些数据:

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

你基本上在路由上使用resolve参数,这样routeProvider在实例化控制器之前等待所有承诺被解决。