简体   繁体   English

如何在mousemove上更新可重复使用的AngularJS服务?

[英]How can this re-usable AngularJS service update on mousemove?

I developed a re-usable AngularJS service that allows the user to start, stop, and re-set a countdown timer from a view by clicking on buttons in the view. 我开发了可重复使用的AngularJS服务,该服务允许用户通过单击视图中的按钮从视图中启动,停止和重置倒数计时器。 The re-usable service can be accessed through any controller that includes it. 可重用服务可以通过包含它的任何控制器进行访问。 The working code for the minimal example countdown app can be viewed by clicking the link to this plnkr . 通过单击此plnkr的链接,可以查看最小示例倒计时应用程序的工作代码。

But I want the timer to be re-set to its max default value every time a user moves the mouse anywhere in the browser window. 但我希望每次用户将鼠标移到浏览器窗口中的任何位置时,将计时器重置为其最大默认值。 This means adding $window.addEventListener(...) somewhere in the service because the service has to be re-usable across any controller, while also responding to any movement of the mouse anywhere over the browser window, even the areas not contained within an HTML element linked to a controller. 这意味着在服务中的某处添加$window.addEventListener(...) ,因为该服务必须可在任何控制器之间重用,同时还必须响应鼠标在浏览器窗口上任何位置的任何移动,甚至是不包含在其中的区域链接到控制器的HTML元素。 Thus, I cannot simply resort to adding ng-mousemove="somemethod()" in the html body tag the way this other example does . 因此,我不能像其他示例那样简单地在html body标签中添加ng-mousemove="somemethod()" I would also prefer to avoid the $rootScope.broadcast approach taken by this other posting because I would like to keep the code isolated in the service as much as possible. 我还希望避免其他文章采用$rootScope.broadcast方法,因为我想尽可能地将代码隔离在服务中。

What specific changes need to be made to the code below so that the timer will be re-set to its default value any time the user moves the mouse anywhere in the browser window? 需要对下面的代码进行哪些特定的更改,以便在用户将鼠标移动到浏览器窗口中的任何位置时将计时器重置为其默认值?

Though all of the code is in the plnkr for easy editing , I am also including it here. 尽管所有代码都在plnkr中以便于编辑 ,但我也在此处包括了它。

index.html is: index.html是:

<!doctype html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Timer</title>
  <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.0/angular.min.js"></script>

    <script src="myTimer.js" type="text/javascript"></script>
    <script src="exampleController.js" type="text/javascript"></script>
    <script src="app.js" type="text/javascript"></script>
</head>
<body ng-app="intervalExample">

<div>
  <div ng-controller="ExampleController">
    Test variable: {{ mytimer.testvariable }}<br>

    Time Remaining : <font color='red'>{{mytimer.timeleft}}</font>
    <br>
    <button type="button" data-ng-click="mytimer.startCountdown()">Start Countdown</button>
    <button type="button" data-ng-click="mytimer.stopCountdown()">Stop Countdown</button>
    <button type="button" data-ng-click="mytimer.resetCountdown()">Reset Timer</button>
  </div>
</div>
</body>
</html>

app.js is: app.js是:

angular.('intervalExample',['ExampleController']);

exampleController.js is: exampleController.js是:

angular
.module('ExampleController', ['mytimer'])
.controller('ExampleController', ['$scope', 'mytimer', function($scope, mytimer) {

    $scope.mytimer = mytimer;
}]);

myTimer.js is: myTimer.js是:

angular
.module('mytimer', [])
.service('mytimer', ['$rootScope', '$interval', function($rootScope, $interval) {

    var $this = this;
    this.testvariable = "some value. ";

        this.timeleft = 15;

        var stop;
        this.startCountdown = function() {
          // Don't start a new countdown if we are already counting down
          if ( angular.isDefined(stop) ) return;

          stop = $interval(function() {
            if ($this.timeleft > 0 ) {
              $this.timeleft = $this.timeleft - 1;
            } else {
              $this.stopCountdown();
            }
         }, 1000);
        };

        this.stopCountdown = function() {
          if (angular.isDefined(stop)) {
            $interval.cancel(stop);
            stop = undefined;
          }
        };

        this.resetCountdown = function() {
          this.timeleft = 15;
        };

//        this.$on('$destroy', function() {
            // Make sure that the interval is destroyed too
//            $this.stopCountdown();
//        });

          function subsFunc() {
            $window.addEventListener('mousemove', function(e) {
            $this.timeleft = 15;
        })
  }

}]);

Issues to consider: 要考虑的问题:

  1. You are never calling subsFunc() and when you do will see that $window is not injected in service 您永远不会调用subsFunc()并且这样做时会看到$window没有注入服务

  2. You will need to debounce the mousemove callback since the event triggers about every pixel. 由于事件会触发每个像素,因此您需要对mousemove回调进行去抖动处理。 Resetting your timer every pixel makes no sense and would cause significant needless digests. 将计时器重置为每个像素都没有意义,并且会导致大量不必要的摘要。

  3. Use of directive for buttons would negate needing to inject in numerous controllers 对按钮使用指令将无需注入大量控制器

  4. Same for timer display ... can be directive and depending on UI combined with buttons 定时器显示相同...可以被指令,并取决于UI和按钮的组合

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM