如何在Angular JS中为`ng-view`做预加载器?

时间:2021-12-09 03:13:37

I use <div ng-view></div> on web page. When I click link in block <div> is loaded HTML template was set in routeProvider. Also together is done request AJAX that returns data that was loaded template.

我在网页上使用

。当我在块
中单击链接时,在routeProvider中设置了HTML模板。另外一起完成了请求AJAX,它返回已加载模板的数据。

Now problem is that after click I get HTML template with empty form, still is working AJAX request. After some seconds form HTML is fiiled data from AJAX.

现在的问题是,点击后我得到了空表格的HTML模板,仍然正在运行AJAX请求。几秒钟之后,HTML表示来自AJAX的数据。

How I can do preloader to page for directory ng-view?

如何为预览器页面查看目录ng-view?

3 个解决方案

#1


It seems that there are some similar questions here:

似乎这里有一些类似的问题:

Also, there a bunch of modules to work with loading animation at http://ngmodules.org. For example, these:

此外,还有一些模块可以在http://ngmodules.org上加载动画。例如,这些:

UPD: I've written a simple solution based on how the angular-loading-bar works. I didn't test it with ng-view, but it seams to work with ui-view. It is not a final solution and have to be polished.

UPD:我根据角度加载条的工作原理编写了一个简单的解决方案。我没有用ng-view测试它,但它接口与ui-view一起工作。它不是最终解决方案,必须进行抛光。

angular.module('ui')

.config(['$httpProvider', function($httpProvider) {
    $httpProvider.interceptors.push('LoadingListener');
}])

.factory('LoadingListener', [ '$q', '$rootScope', function($q, $rootScope) {
    var reqsActive = 0;

    function onResponse() {
        reqsActive--;
        if (reqsActive === 0) {
            $rootScope.$broadcast('loading:completed');
        }
    }

    return {
        'request': function(config) {
            if (reqsActive === 0) {
                $rootScope.$broadcast('loading:started');
            }
            reqsActive++;
            return config;
        },
        'response': function(response) {
            if (!response || !response.config) {
                return response;
            }
            onResponse();
            return response;
        },
        'responseError': function(rejection) {
            if (!rejection || !rejection.config) {
                return $q.reject(rejection);
            }
            onResponse();
            return $q.reject(rejection);
        },
        isLoadingActive : function() {
            return reqsActive === 0;
        }
    };
}])

.directive('loadingListener', [ '$rootScope', 'LoadingListener', function($rootScope, LoadingListener) {

    var tpl = '<div class="loading-indicator" style="position: absolute; height: 100%; width: 100%; background-color: #fff; z-index: 1000">Loading...</div>';

    return {
        restrict: 'CA',
        link: function linkFn(scope, elem, attr) {
            var indicator = angular.element(tpl);
            elem.prepend(indicator);

            elem.css('position', 'relative');
            if (!LoadingListener.isLoadingActive()) {
                indicator.css('display', 'none');
            }

            $rootScope.$on('loading:started', function () {
                indicator.css('display', 'block');
            });
            $rootScope.$on('loading:completed', function () {
                indicator.css('display', 'none');
            });
        }
    };
}]);

It can be used like this:

它可以像这样使用:

<section class="content ui-view" loading-listener></section>

#2


You can try something like this(simplest solution):

你可以试试这样的东西(最简单的解决方案):

  1. Set your loader animation/picture:<div class="loader" ng-show="isLoading"></div>

    设置加载器动画/图片:

  2. On div element add click event:

    在div元素上添加click事件:

  3. Then AJAX request success set isLoading=true
  4. 然后AJAX请求成功设置isLoading = true

#3


Download javascript and css files from PACE Loader. Playing around with pace loader using ng-views . Hope this helps someone trying to use PACE.JS with Angular. In this example I am using ng-router to navigate between views.

从PACE Loader下载javascript和css文件。使用ng-views使用步速加载器。希望这有助于某人尝试将PACE.JS与Angular一起使用。在这个例子中,我使用ng-router在视图之间导航。

app.js

var animateApp = angular.module('route-change-loader', ['ngRoute']);

var slowResolve = function(slowDataService){
    return slowDataService.getContacts();
  };
  slowResolve.$inject = ['slowDataService'];

// ROUTING ===============================================
// set our routing for this application
  // each route will pull in a different controller
  animateApp.config(function($routeProvider) {

    $routeProvider

    // home page
    .when('/route1', {
      templateUrl: 'route1.html',
      controller: 'slowCtrl',
      controllerAs:'ctrl',
      resolve: {
        contacts:slowResolve
      }
    })
    .otherwise({
      templateUrl:'default.html'
    });
  });


var SlowCtrl = function(contacts) {
  this.contacts = contacts;
};
  SlowCtrl.$inject = ['contacts'];

  angular.extend(SlowCtrl.prototype, {
    message:'Look Mom, No Lag!',
    contacts: []
  });

animateApp.controller('slowCtrl', SlowCtrl);


  var SlowDataService = function($timeout){
      this.$timeout = $timeout;
    };
    SlowDataService.$inject = ['$timeout'];

    angular.extend(SlowDataService.prototype, {
      contacts:[{
        name:'Todd Moto',
        blog:'http://toddmotto.com/',
        twitter:'@toddmotto'
      },{
        name:'Jeremy Likness',
        blog:'http://csharperimage.jeremylikness.com/',
        twitter:'@jeremylikness'
      },{
        name:'John Papa',
        blog:'http://www.johnpapa.net/',
        twitter:'@John_Papa'
      },{
        name:'Josh Carroll',
        blog:'http://www.technofattie.com/',
        twitter:'@jwcarroll'
      }],
      getContacts:function(){
        var _this = this;
        return this.$timeout(function(){
          return angular.copy(_this.contacts);
        }, 1000);
      }
    });

animateApp.service('slowDataService', SlowDataService);

index.html

<!DOCTYPE html>
<html lang="en-us">
<head>
  <meta charset="utf-8">
  <title>Test Example</title>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
  <script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/js/bootstrap.min.js"></script>
  <link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css">
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.4.0/css/font-awesome.min.css">
  <link rel="stylesheet" href="pace.css">
  <script src="http://code.angularjs.org/1.2.13/angular.js"></script>
  <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.13/angular-route.js"></script>
  <script src="app.js"></script>
  <script src="pace.js"></script>

</head>
<body ng-app="route-change-loader">
  <div class="container">
    <div class="masthead">
      <ul class="nav nav-tabs">
        <li>
          <a href="#/default">Default</a>
        </li>
        <li>
          <a href="#/route1">Slow Loading Controller</a>
        </li>
      </ul>
    </div>
    <!-- Jumbotron -->
    <div class="row">
      <route-loading-indicator></route-loading-indicator>
      <div ng-if="!isRouteLoading" class="col-lg-12" ng-view=""></div>
    </div>
    <!-- Site footer -->
    <div class="footer">
      <p>by <b>Ritesh Karwa</b> </a>
      </p>
    </div>
  </div>
</body>

</html>

default.html

<h1>Click on the tabs to change routes</h1>

route1.html

<h1>{{ctrl.message}}</h1>
<table class="table table-striped">
  <thead>
    <tr>
      <th>Name</th>
      <th>Blog</th>
      <th>Twitter</th>
    </tr>
  </thead>
  <tbody>
    <tr ng-repeat='contact in ctrl.contacts'>
      <td>{{contact.name}}</td>
      <td>{{contact.blog}}</td>
      <td>{{contact.twitter}}</td>
    </tr>
  </tbody>
</table>

#1


It seems that there are some similar questions here:

似乎这里有一些类似的问题:

Also, there a bunch of modules to work with loading animation at http://ngmodules.org. For example, these:

此外,还有一些模块可以在http://ngmodules.org上加载动画。例如,这些:

UPD: I've written a simple solution based on how the angular-loading-bar works. I didn't test it with ng-view, but it seams to work with ui-view. It is not a final solution and have to be polished.

UPD:我根据角度加载条的工作原理编写了一个简单的解决方案。我没有用ng-view测试它,但它接口与ui-view一起工作。它不是最终解决方案,必须进行抛光。

angular.module('ui')

.config(['$httpProvider', function($httpProvider) {
    $httpProvider.interceptors.push('LoadingListener');
}])

.factory('LoadingListener', [ '$q', '$rootScope', function($q, $rootScope) {
    var reqsActive = 0;

    function onResponse() {
        reqsActive--;
        if (reqsActive === 0) {
            $rootScope.$broadcast('loading:completed');
        }
    }

    return {
        'request': function(config) {
            if (reqsActive === 0) {
                $rootScope.$broadcast('loading:started');
            }
            reqsActive++;
            return config;
        },
        'response': function(response) {
            if (!response || !response.config) {
                return response;
            }
            onResponse();
            return response;
        },
        'responseError': function(rejection) {
            if (!rejection || !rejection.config) {
                return $q.reject(rejection);
            }
            onResponse();
            return $q.reject(rejection);
        },
        isLoadingActive : function() {
            return reqsActive === 0;
        }
    };
}])

.directive('loadingListener', [ '$rootScope', 'LoadingListener', function($rootScope, LoadingListener) {

    var tpl = '<div class="loading-indicator" style="position: absolute; height: 100%; width: 100%; background-color: #fff; z-index: 1000">Loading...</div>';

    return {
        restrict: 'CA',
        link: function linkFn(scope, elem, attr) {
            var indicator = angular.element(tpl);
            elem.prepend(indicator);

            elem.css('position', 'relative');
            if (!LoadingListener.isLoadingActive()) {
                indicator.css('display', 'none');
            }

            $rootScope.$on('loading:started', function () {
                indicator.css('display', 'block');
            });
            $rootScope.$on('loading:completed', function () {
                indicator.css('display', 'none');
            });
        }
    };
}]);

It can be used like this:

它可以像这样使用:

<section class="content ui-view" loading-listener></section>

#2


You can try something like this(simplest solution):

你可以试试这样的东西(最简单的解决方案):

  1. Set your loader animation/picture:<div class="loader" ng-show="isLoading"></div>

    设置加载器动画/图片:

  2. On div element add click event:

    在div元素上添加click事件:

  3. Then AJAX request success set isLoading=true
  4. 然后AJAX请求成功设置isLoading = true

#3


Download javascript and css files from PACE Loader. Playing around with pace loader using ng-views . Hope this helps someone trying to use PACE.JS with Angular. In this example I am using ng-router to navigate between views.

从PACE Loader下载javascript和css文件。使用ng-views使用步速加载器。希望这有助于某人尝试将PACE.JS与Angular一起使用。在这个例子中,我使用ng-router在视图之间导航。

app.js

var animateApp = angular.module('route-change-loader', ['ngRoute']);

var slowResolve = function(slowDataService){
    return slowDataService.getContacts();
  };
  slowResolve.$inject = ['slowDataService'];

// ROUTING ===============================================
// set our routing for this application
  // each route will pull in a different controller
  animateApp.config(function($routeProvider) {

    $routeProvider

    // home page
    .when('/route1', {
      templateUrl: 'route1.html',
      controller: 'slowCtrl',
      controllerAs:'ctrl',
      resolve: {
        contacts:slowResolve
      }
    })
    .otherwise({
      templateUrl:'default.html'
    });
  });


var SlowCtrl = function(contacts) {
  this.contacts = contacts;
};
  SlowCtrl.$inject = ['contacts'];

  angular.extend(SlowCtrl.prototype, {
    message:'Look Mom, No Lag!',
    contacts: []
  });

animateApp.controller('slowCtrl', SlowCtrl);


  var SlowDataService = function($timeout){
      this.$timeout = $timeout;
    };
    SlowDataService.$inject = ['$timeout'];

    angular.extend(SlowDataService.prototype, {
      contacts:[{
        name:'Todd Moto',
        blog:'http://toddmotto.com/',
        twitter:'@toddmotto'
      },{
        name:'Jeremy Likness',
        blog:'http://csharperimage.jeremylikness.com/',
        twitter:'@jeremylikness'
      },{
        name:'John Papa',
        blog:'http://www.johnpapa.net/',
        twitter:'@John_Papa'
      },{
        name:'Josh Carroll',
        blog:'http://www.technofattie.com/',
        twitter:'@jwcarroll'
      }],
      getContacts:function(){
        var _this = this;
        return this.$timeout(function(){
          return angular.copy(_this.contacts);
        }, 1000);
      }
    });

animateApp.service('slowDataService', SlowDataService);

index.html

<!DOCTYPE html>
<html lang="en-us">
<head>
  <meta charset="utf-8">
  <title>Test Example</title>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
  <script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/js/bootstrap.min.js"></script>
  <link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css">
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.4.0/css/font-awesome.min.css">
  <link rel="stylesheet" href="pace.css">
  <script src="http://code.angularjs.org/1.2.13/angular.js"></script>
  <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.13/angular-route.js"></script>
  <script src="app.js"></script>
  <script src="pace.js"></script>

</head>
<body ng-app="route-change-loader">
  <div class="container">
    <div class="masthead">
      <ul class="nav nav-tabs">
        <li>
          <a href="#/default">Default</a>
        </li>
        <li>
          <a href="#/route1">Slow Loading Controller</a>
        </li>
      </ul>
    </div>
    <!-- Jumbotron -->
    <div class="row">
      <route-loading-indicator></route-loading-indicator>
      <div ng-if="!isRouteLoading" class="col-lg-12" ng-view=""></div>
    </div>
    <!-- Site footer -->
    <div class="footer">
      <p>by <b>Ritesh Karwa</b> </a>
      </p>
    </div>
  </div>
</body>

</html>

default.html

<h1>Click on the tabs to change routes</h1>

route1.html

<h1>{{ctrl.message}}</h1>
<table class="table table-striped">
  <thead>
    <tr>
      <th>Name</th>
      <th>Blog</th>
      <th>Twitter</th>
    </tr>
  </thead>
  <tbody>
    <tr ng-repeat='contact in ctrl.contacts'>
      <td>{{contact.name}}</td>
      <td>{{contact.blog}}</td>
      <td>{{contact.twitter}}</td>
    </tr>
  </tbody>
</table>