【问题标题】:AngularJS: show loading HTML until data is loadedAngularJS:显示加载 HTML,直到加载数据
【发布时间】:2013-04-16 22:57:02
【问题描述】:

如何让 AngularJS 显示加载微调器,直到数据加载完成?

如果我的控制器静态设置了$scope.items = [{name: "One"}],并且有一个填充$scope.items[0]['lateLoader'] = "Hello" 的AJAX 加载器,我希望在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 为空,微调器被替换为空。

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

【问题讨论】:

  • 为什么不将加载器图像静态地放在标记中?

标签: javascript angularjs angularjs-ng-repeat


【解决方案1】:

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

【讨论】:

  • setTimeout 只是用来模拟等待,虽然你是对的,使用 $timeout 会更好。
  • $timeout 很有用,因为它自动将回调包装到 $apply 中。 IE。您可以从示例中删除 $scope.$apply(function() {
【解决方案2】:

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

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

那么,在我看来,我可以使用:

ng-hide="customer.loaded"

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

【讨论】:

  • 这是迄今为止最好的解决方案。
【解决方案3】:

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

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

【讨论】:

    【解决方案4】:

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

    这里有一些关于自定义指令的链接

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

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

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

    【讨论】:

    • 我同意这一点,尽管他也可以根据数据是否存在(某些条件)做一个ng-showng-hide
    • @lucuma 是的,但它似乎是一个很好的可重复使用的东西,它是自己的指令。
    • 我是 Angular 的新手——如果你有一个例子或一个文档链接真的很有帮助,尽管我很高兴自己去寻找文档!
    • @JP。我给你几个链接开始
    猜你喜欢
    • 2016-03-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-07
    • 2019-01-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多