22

在数据加载完成之前,如何让 AngularJS 显示加载微调器?

如果我的控制器已$scope.items = [{name: "One"}]静态设置,并且填充了 AJAX 加载器$scope.items[0]['lateLoader'] = "Hello",我希望微调器显示直到 AJAX 加载完成,然后使用检索到的数据填充绑定范围。

<ul ng-repeat="item in items">
  <li>
    <p>Always present: {{item.name}}</p>
    <p>Loads later: <span ng-bind="item.lateLoader"><i class="icon icon-refresh icon-spin"></i></span></p>
  </li>
</ul>

此代码立即填充绑定跨度,并且作为item.lateLoader空的微调器被替换为空。

我应该如何干净地做到这一点?

4

4 回答 4

23

我会根据其他答案创建一个自定义指令,但这里是在没有指令的情况下如何做到这一点,这可能是在进入更复杂的功能之前学习的好主意。有几点需要注意:

  1. 使用 setTimeout 模拟 ajax 调用
  2. 加载图标已预加载,并在数据加载时隐藏。只是一个简单的 ng-hide 指令。
  3. 在我的示例中没有加载图像,只是一些隐藏的文本(显然您的 html 将具有正确的 css 引用)。

演示: http ://plnkr.co/edit/4XZJqnIpie0ucMNN6egy?p=preview

看法:

<ul >
  <li ng-repeat="item in items">
    <p>Always present: {{item.name}}</p>
    <p>Loads later: {{item.lateLoader}} <i ng-hide="item.lateLoader"  class="icon icon-refresh icon-spin">loading image i don't have</i></p>
  </li>
</ul>

控制器:

app.controller('MainCtrl', function($scope) {
  $scope.name = 'World';
  $scope.items = [{name: "One"}];
  setTimeout(function() {
    $scope.$apply(function() {
     $scope.items[0].lateLoader = 'i just loaded';  
    });
  }, 1000);
});
于 2013-04-23T16:47:00.993 回答
22

实际上,我已经为此使用了一段时间的解决方案,该解决方案效果很好,并且在我看来比使用超时更好。我正在使用 $resource,但您可以使用 $http 做同样的事情。在我的 $resource 对象上,我在以下代码中添加了将加载设置为 true 的位。

$scope.customer = $resource(dataUrl + "/Course/Social/" + courseName)
    .get({}, function (data) { data.loaded = true; });

然后,在我看来,我可以使用:

ng-hide="customer.loaded"

当然,我不会直接在控制器中使用 $resource,而是将其提取到 customerRepository 服务中,但在这里以这种方式显示更简单。

于 2014-02-13T17:27:23.963 回答
5

我会创建自定义指令并使用微调器放置默认标记。

以下是自定义指令的一些链接

1) Egghead 视频很棒!http://www.egghead.io/video/xoIHkM4KpHM

2) 关于指令的官方 Angular 文档http://docs.angularjs.org/guide/directive

3)在 60 分钟内很好地概述了角度http://weblogs.asp.net/dwahlin/archive/2013/04/12/video-tutorial-angularjs-fundamentals-in-60-ish-minutes.aspx

于 2013-04-23T16:29:51.520 回答
0

@lucuma,

很好的答案,另一种方法是注入 $timeout 并替换本机超时功能:

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

app.controller('MainCtrl', function($scope, $timeout) {

        $scope.name = 'World';
        $scope.items = [{name: "One"}];
        $timeout(function() {
                $scope.$apply(function() {
                        $scope.items[0].lateLoader = 'i just loaded';  
                });
        }, 1000);
});
于 2013-10-24T17:43:28.047 回答