Angular $ interval独立于控制器运行 [英] Having an Angular $interval running independent of controller

查看:33
本文介绍了Angular $ interval独立于控制器运行的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在may应用程序上我有不同的页面,它们都有自己的控制器.其中一个具有$ interval函数,比方说一个计时器.单击一个按钮将启动此间隔功能,该功能每秒更新一次.我想拥有的是,我希望能够转到应用程序中的任何其他页面(调用不同的控制器),但是我希望我的时间间隔继续运行,直到我从第一个控制器显式停止它.可以说是 rootScope间隔.我该怎么办?

I have different pages on may application which have their own controllers. One of them has an $interval function, let's say a timer. Click on a button will start this interval function, which updates itself every second. What i want to have is, i want to be able to go to any other page in my application (calling different controllers), but i want my interval to continue running until i stop it explicitly from the first controller. A rootScope interval so to speak. How can i do it?

感谢克里斯和帕特里克,我现在有了一个简单的服务,看起来像这样:

Thanks to Chris and Patrick i now have a simple Service, looks like this:

  .service('TimerService', function($interval) {
    var promise;
    var timerSeconds = 0;

    this.start = function () {
      promise = $interval(function () {
        timerSeconds++;
      }, 1000);
    };

    this.stop = function () {
      promise.cancel(interval);
      timerSeconds = 0;
    };

    this.getTimer = function() {
      return timerSeconds;
    }
  })

我还在此服务中存储了我的当前值(timerSeconds).但是如何将这个值同步到我的控制器?该服务使timerSeconds递增,并且在我的控制器开始时,我通过其getTimer()函数从该服务中读取了它,但显然不会在我的控制器上对其进行更新. 如何将该服务属性与本地属性同步?

I store also my current value (timerSeconds) in this service. But how can i sync this value to my controller? The service increments the timerSeconds, and at the beginning of my controller i read it from this service through its getTimer() function, but it clearly will not be updated on my controller. How can i sync this service attribute with my local attribute?

当我将我的service属性定义为一个对象,将timerSeconds定义为该对象内部的数字时(似乎无法同步原语):

when i define my service attribute as an object and the timerSeconds as number inside that object (it seems primitives cannot be synced):

var timer = {seconds : 0};

this.getTimer = function() {
  return timer;
}

并通过该吸气剂从我的控制器中获取该对象:

and get this object from my controller through that getter:

vm.timer = TimerService.getTimer();

它们都是同步的.

推荐答案

不要费心将其添加到$ rootScope.使用可在应用程序中任何位置使用的服务.这是一个可以启动和停止的单例计时器.在服务本身中定义intervalTimeout,或者如果您想真正灵活一些,请在提供程序中定义(对于此示例而言,可能会适得其反).

Don't bother adding it to $rootScope. Use a service that can be used anywhere in the app. Here is a singleton timer that can start and stop. Define the intervalTimeout in the service itself, or if you want to be really flexible, do so in a provider (probably overkill for this example).

angular.module('myApp', [])

.service('AppCallback', function ($interval) {
    var states = states = {
        PENDING: 0,
        STARTED: 1
    }, intervalTimeout = 3000, // Set this
    interval;

    this.states = states;
  
    this.state = states.PENDING;
    this.start = function (callback) {
        if (this.state !== states.PENDING) {
            return;
        }

        interval = $interval(callback, intervalTimeout);
        this.state = states.STARTED;
    }

    this.stop = function () {
        if (this.state !== states.STARTED) {
            return;
        }
        $interval.cancel(interval);
        this.state = states.PENDING;
    };
})

.controller('MainController', function ($scope, AppCallback) {
  var vm = {},
      count = 0;
  
  vm.toggle = function toggle() {
    if (AppCallback.state === AppCallback.states.PENDING) {
      AppCallback.start(function () {
        vm.data = 'Ticked ' + (++count) + ' times.';
      });
     } else {
       AppCallback.stop();
     }
  };
  
  
  $scope.vm = vm;
});

<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" ng-controller="MainController">
  {{vm.data}}
  <br />
  <button ng-click="vm.toggle()">Toggle</button>
</div>

这篇关于Angular $ interval独立于控制器运行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆