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

3

这个主题已经被问过了,但是在我的情况下我无法弄清楚该怎么做。

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

2
或许AngularJS的创始人的回答可以帮到你:https://dev59.com/xGct5IYBdhLWcg3wmOdO#11972028 - L42y
你也可以将 AJAX 请求的结果分配给 $scope 中的某个变量,然后在 HTML 中使用 ng-show。 - boxed
1
这是一种相当可靠的方法。它比使用ng-show或ng-hide要好得多,因为在控制器中,您已经拥有了数据,并且可以编写更多同步代码。尽管如此,这更适合于代码审查网站而不是SO,因为您没有问题,而是在寻找代码改进。 - Umur Kontacı
@L42y 有趣的是,Misko也问了那个问题。 - Shomz
2个回答

1
AngularJS的重点在于你可以加载模板和其他内容,并等待数据加载,它是异步的。您的视图应该使用ng-hide、ng-show来检查控制器的作用域,以便当作用域中的数据更新时,视图将显示。您还可以显示旋转图标,以便用户不会感觉网站已经崩溃。

我理解你的意思,当你加载数据以在视图上显示时,但是你可能需要基于异步加载取消路由。 - Bruno Peres

1
回答这个问题,您在呈现视图之前显式加载数据的方式似乎是正确的。请记住,这可能不会提供最佳体验,因为需要一些时间来解决问题,这可能会给人留下应用停止运行的印象。
可以查看 John Pappa's blog 的示例,使用 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会在实例化控制器之前等待所有的promise被解决。请参考文档获取更多信息。

使用UI Router时,在声明状态时,请查看“resolve”属性的文档:http://angular-ui.github.io/ui-router/site/#/api/ui.router.state.$stateProvider#methods_state - Bruno Peres

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接