如何在AngularJS / ui-router中跟踪长时间运行的异步请求

时间:2022-01-13 15:21:18

I am building an Angular app using state hierarchy provided by the angular-ui/ui-router library.

我正在使用Angular -ui/ui-router库提供的状态层次结构构建一个有棱角的应用程序。

I have a request that takes many minutes to complete, so the goal is to POST to a request resource and then poll the server to determine when the request completes. The app is quite large and different areas of the site are organized into different decoupled modules, but the header is managed by a common root state.

我有一个需要很多分钟才能完成的请求,所以目标是向一个请求资源发布,然后轮询服务器,以确定请求何时完成。这个应用程序非常大,站点的不同区域被组织成不同的解耦模块,但是header是由一个通用的根状态管理的。

In order to message the completion event to the user without disturbing their browsing session, I would like to:

为了向用户发送完成事件,而不打扰他们的浏览会话,我想:

  • Add a "loading" spinner to the header of the app when the request is made
  • 当发出请求时,向应用程序的头部添加一个“加载”微调控制项
  • Allow the user to continue browsing the site but retain the "loading" spinner
  • 允许用户继续浏览网站,但保留“加载”转轮
  • Replace the spinner with a "check" icon once the polling determines that the request has been completed.
  • 当轮询确定请求已完成时,用“检查”图标替换该转轮。

How can i encapsulate this process and allow it to continue running through multiple state transitions?

如何封装此流程并允许它继续运行多个状态转换?

2 个解决方案

#1


1  

I'm not entirely sure how ui-router works, but if it's anything like $routeProvider (or you're using $routeProvider as well), you can assign a controller to the "header of the app" and let that controller do the work.

我不完全确定ui-router是如何工作的,但是如果它是类似于$routeProvider(或者您也在使用$routeProvider)的东西,那么您可以给“应用的头”分配一个控制器,让那个控制器来完成工作。

Below is a basic example of how it would work. _handleLoad simulates polling the server, and when it's all done, you can change the header easily (or the rest of your site using $broadcast). The $routeProvider let's the user browse the site while the HeaderCtrl continues executing on the page.

下面是它如何工作的一个基本示例。_handleLoad模拟轮询服务器,完成后,您可以轻松地更改header(或使用$broadcast更改站点的其他部分)。$routeProvider让用户浏览站点,而HeaderCtrl继续在页面上执行。

http://plnkr.co/edit/EYqcjhX8kI1GmkYs5VZe?p=preview

http://plnkr.co/edit/EYqcjhX8kI1GmkYs5VZe?p=preview

app.controller('HeaderCtrl', function ($scope, $timeout) {
  var _i = 0,
      _handleLoad = function () {
        console.log('checking..');
        // TODO check the server here, fire the $timeout in the callback if the process isn't complete
        if (_i == 3) {
          $scope.loading = false;
          _i = 0;
          $scope.headerText = 'we have loaded something';
          console.log('all done');
          return;
        }
        _i += 1;

        $timeout(_handleLoad, 1000);
      };

  $scope.headerText = 'click here to load something';
  $scope.loading = false;

  $scope.load = function () {
    $scope.loading = true;
    _handleLoad();
  }
});

#2


2  

You can create an abstract state that child states will inherit from. Add a service that polls for the status of the long running request. All of the children states will have access to the abstract controller via the $scope.$parent property.

您可以创建子状态将继承的抽象状态。添加用于轮询长期运行请求状态的服务。所有子状态都可以通过$范围访问抽象控制器。美元的父属性。

#1


1  

I'm not entirely sure how ui-router works, but if it's anything like $routeProvider (or you're using $routeProvider as well), you can assign a controller to the "header of the app" and let that controller do the work.

我不完全确定ui-router是如何工作的,但是如果它是类似于$routeProvider(或者您也在使用$routeProvider)的东西,那么您可以给“应用的头”分配一个控制器,让那个控制器来完成工作。

Below is a basic example of how it would work. _handleLoad simulates polling the server, and when it's all done, you can change the header easily (or the rest of your site using $broadcast). The $routeProvider let's the user browse the site while the HeaderCtrl continues executing on the page.

下面是它如何工作的一个基本示例。_handleLoad模拟轮询服务器,完成后,您可以轻松地更改header(或使用$broadcast更改站点的其他部分)。$routeProvider让用户浏览站点,而HeaderCtrl继续在页面上执行。

http://plnkr.co/edit/EYqcjhX8kI1GmkYs5VZe?p=preview

http://plnkr.co/edit/EYqcjhX8kI1GmkYs5VZe?p=preview

app.controller('HeaderCtrl', function ($scope, $timeout) {
  var _i = 0,
      _handleLoad = function () {
        console.log('checking..');
        // TODO check the server here, fire the $timeout in the callback if the process isn't complete
        if (_i == 3) {
          $scope.loading = false;
          _i = 0;
          $scope.headerText = 'we have loaded something';
          console.log('all done');
          return;
        }
        _i += 1;

        $timeout(_handleLoad, 1000);
      };

  $scope.headerText = 'click here to load something';
  $scope.loading = false;

  $scope.load = function () {
    $scope.loading = true;
    _handleLoad();
  }
});

#2


2  

You can create an abstract state that child states will inherit from. Add a service that polls for the status of the long running request. All of the children states will have access to the abstract controller via the $scope.$parent property.

您可以创建子状态将继承的抽象状态。添加用于轮询长期运行请求状态的服务。所有子状态都可以通过$范围访问抽象控制器。美元的父属性。