37

以下代码通过服务读取并在网页上显示特定“页面类别”(字符串)的“页面”对象列表。使用 $routeProvider.when() 中的解析对象属性,我可以推迟更新视图,直到新值准备好。

两个问题:

  1. 当要求一个新的页面列表时,我想显示一个加载图标。当从服务器读取开始(并且应该显示加载图标)时,我如何检测(以非黑客方式)事件?我想我可以在服务中做类似 $('.pages-loading-icon').show() 的事情,但是发现太依赖于 gui 太放置在服务中。

  2. 当新值准备好时,我希望旧的淡出而新的淡入。这样做的“角度”方式是什么?我曾尝试使用 $watch 在控制器中执行此操作,但这会导致在淡出开始前不久显示新值。

编码:

应用程序.js:

$routeProvider.when('/:cat', { templateUrl: 'partials/view.html', controller: RouteCtrl, resolve: RouteCtrl.resolve});

控制器.js:

function RouteCtrl($scope, $routeParams, pages) {
        $scope.params = $routeParams;
        $scope.pages = pages;
    }

RouteCtrl.resolve={
    pages: function($routeParams, Pages){
        if($routeParams.hasOwnProperty('cat')){
            return Pages.query($routeParams.cat);
        }
    }
}

services.js: 最后读取的页面存储在 currentPages 中,其类别存储在 lastCat 中。

factory('Pages', function($resource, $q, $timeout){
    return {
        res: $resource('jsonService/cat=:cat', {}, {
            query: {method:'GET', params:{cat:'cat'}, isArray:true}
        }),
        lastCat: null,
        currentPages: null,
        query: function(cat) {
            var res = this.res;
            if(cat != this.lastCat){
                var deferred = $q.defer();
                var p = res.query({'cat':cat}, function(){
                    deferred.resolve(p);
                });
                this.lastCat = cat;
                this.currentPages = deferred.promise;
            }
            return this.currentPages;
        }
    };
})

视图.html

<ul >
    <li ng-repeat="page in pages">
        <a href="#{{params.cat}}/{{page.slug}}">{{page.title}}</a>
    </li>
</ul>
4

6 回答 6

61

不确定这是否会在您的代码中起作用,因为您有 $resource 集成。但可能值得研究角度事件:$routeChangeStart$routeChangeSuccess.

在 html 中:

<span ng-show="isViewLoading"> loading the view... </span>

在控制器中(它定义了上面 html 的范围):

$scope.isViewLoading = false;
$scope.$on('$routeChangeStart', function() {
  $scope.isViewLoading = true;
});
$scope.$on('$routeChangeSuccess', function() {
  $scope.isViewLoading = false;
});
$scope.$on('$routeChangeError', function() {
  $scope.isViewLoading = false;
});
于 2012-09-12T05:16:59.547 回答
4

角度的路由系统似乎有点有限..

这为我解决了这个问题:
http ://www.bennadel.com/blog/2420-Mapping-AngularJS-Routes-Onto-URL-Parameters-And-Client-Side -事件.htm

此外,关于触发两次的事件:如果您设置路线映射到“a/b/c”,角度会自动设置另一条路线,“a/b/c/”(带有斜杠)重定向到第一个(和反之亦然),并且都触发事件。我只是测试是否存在路由参数。

关于路由系统的有限条件:有这种从角度的拉动,以扩展它的能力。

于 2012-11-02T14:38:06.280 回答
2

您将需要使用 ,$rootScope因为监控控制器$scope仅限于控制器,并且碰巧您正在从一个视图(一个控制器)切换到另一个视图(另一个控制器)。因此,有一个适合所有人的代码是有意义的。

$rootScope.$on('$stateChangeStart', 
function(event, toState, toParams, fromState, fromParams){ ... })

在该函数中设置$rootScope.isLoadingState将显示您的加载指示器。

然后使用

$rootScope.$on('$stateChangeSuccess', 
function(event, toState, toParams, fromState, fromParams){ ... })

取消设置该变量。

完整参考这里

于 2014-04-05T19:45:14.447 回答
1

您还可以使用 ng-show 指令。只需检查您的模型是否为空并显示一个 DOM 子集,如下所示:

    <!-- model not ready -->
    <div style="width: 200" ng-show="lines == ''">
      <div class="progress progress-striped active">
         <div class="bar" style="width: 0%;"></div>
      </div>
    </div>

    <!-- your model code -->
    <ul class="nav nav-tabs nav-stacked">
      <li ng-repeat="line in lines">
        {{line.Id}}
      </li>
    </ul>
于 2013-05-28T12:17:15.250 回答
1

我喜欢'ng-show'......但是'ui-if'Angular UI 项目的更好恕我直言......因为从 DOM 中删除 HTML 代码......

<span ui-if = "isViewLoading"> loading the view... </span>

_e

于 2012-11-26T22:59:04.110 回答
0

您可以创建一个指令,该指令将根据您在服务调用之前和之后发送的广播显示,您可以将其放在 $rootScope 上。因此,如果您正在调用工厂来处理发出通用 POST/GET 调用,那么就在调用之前,您可以在 $rootScope 上调用一个函数,例如“$rootScope.startLoading()”,当它完成调用“$rootScope. doneLoading()”,这些方法中的每一个都广播一个事件,供您接收指令。然后你只需处理你的指令来捕获事件,"scope.$on("startLoading", func(..." 并让它在DOM中插入/显示一个加载div模板并运行,然后还有一个catch for完成加载以删除/隐藏它。

这样你就可以有一个很好的一般加载覆盖。

于 2013-10-01T21:57:08.923 回答