当控制器变为后台(或无效)时需要停止正在进行的操作

时间:2015-02-23 18:11:06

标签: angularjs controller routing angularjs-routing angularjs-controller

我正在编写我的第一个AngularJS应用程序。着陆页有两个链接#/view1#/view2。每个链接都会调用单个控制器来单独呈现<div ng-view></div>

view1Ctrl将定期从服务器获取数据。我每隔X秒就可以在控制台中看到ajax调用。现在我点击#/view2,应用应该使用view2Ctrl。我希望view1Ctrl不再从服务器获取数据。但实际上确实如此。

.controller('View1Ctrl', function($scope, $http) {
  $scope.update = function() {
    $http.get('/api/foo')
      .success(function(data) { /* got new data */ })
      .error(function(data) { /* error occurred */ })
      .finally(function() {
        setTimeout($scope.update, 1000);
      });
  }
  $scope.update();
});

我有两个问题:

  1. 控制器在初始化后始终处于活动状态。
  2. 停止任何后台控制器的最佳做法是什么?我的想法是检查$location.path()

  3. 更新1:

    控制器实际上已被销毁。但是操作update将自己调用它,因此操作将被称为无穷无尽。

    我当前的解决方法将检查当前位置是否已更改。所以它有效。如果它存在,我正在寻找一种更优雅的方式。

    .controller('View1Ctrl', function($scope, $http) {
      $scope.update = function(path) {
        $http.get('/api/foo')
          .success(function(data) { /* got new data */ })
          .error(function(data) { /* error occurred */ })
          .finally(function() {
            if (path === $location.path()) {
              setTimeout($scope.update, 1000, path);
            }
          });
      }
      $scope.update($location.path());
    });
    

    更新2:

    更好的方法是观察破坏并取消正在进行的超时承诺。谢谢@pankajparkar

    .controller('View1Ctrl', function($scope, $http, $timeout) {
      var timeoutPromise;
      $scope.$on("$destroy", function(){
        $timeout.cancel(timeoutPromise);
      });
      $scope.update = function() {
        $http.get('/api/foo')
          .success(function(data) { /* got new data */ })
          .error(function(data) { /* error occurred */ })
          .finally(function() {
             timeoutPromise = $timeout($scope.update, 1000);
          });
      }
      $scope.update();
    });
    

1 个答案:

答案 0 :(得分:2)

我认为你在body标签或ng-view的父级上提到了ng-controller,在你的情况下,你应该从你的$routeProvider加载控制器来处理它,

<强>配置

app.config(function($routeProvider) {
  $routeProvider
    .when('/view1', {
      templateUrl: 'view1.html',
      controller: 'view1Ctrl' //load specific controller from here
    })
    .when('/view2', {
      templateUrl: 'view2.html',
      controller: 'view2Ctrl' //load specific controller from here
    })
    .otherwise({
      redirectTo: '/view1'
    });
});

<强> HTML

  <div class="wizard">
    <ng-view></ng-view>
  </div>

以下是您的问题的答案。

  1. 现在,当$routeProvider加载view1.html时,view1Ctrl将存在,只要用户导航到view2.htmlview1Ctrl就会停止其​​工作{{1}如你在路线配置中提到的那样,将会出现一张图片。
  2. 您应始终使用view2Ctrl$routeProviderangular-ui-router)在您的应用程序中设置路由,并根据路由加载$stateProvidertemplates 。无需检查controller
  3. Working Plunkr

    更新

    你的问题是重复的函数调用,即使在控制器作用域从DOM中消失之后,它也在后台运行。 重定向到其他控制器时清除此功能的最佳方法。 我建议您将$location.path()承诺(使用$timeout将其更改为setTimeout)放在一个java脚本变量中,并在离开时取消(取消注册控制器)。虽然离开控制器$timeout事件会被angular调度,这就像控制器的$destroy一样,你可以使用它,你可以取消它内部的destruct-or承诺。

    <强> CODE

    $timeout

    Plunkr取消承诺var timeoutPromise = setTimeout($scope.update, 1000); $scope.$on("$destroy", function(){ $timeout.cancel(timeoutPromise); }); Reference Link

    希望这可以帮助你,谢谢。