来自异步服务的AngularJS绑定值

时间:2018-11-12 18:29:14

标签: angularjs angularjs-scope

由于Angularjs binding value from service中的@sehaxx,已经解决了一些错误,我想在示例中引入异步,如以下代码所示,其中变量是异步初始化的,其值未反映在视图中。

(function(angular) {
  'use strict';
angular.
module('myServiceModule', []).
  controller('MyController', ['$scope', 'notify','$log', function($scope, notify, $log) {
    this.clickCount = 0;
    this.clickLimit = notify.clickLimit();
    this.callNotify = function(msg) {
        notify.push(msg);
        this.clickCount = notify.clickCount();
        $log.debug("[controller] Click count is now", this.clickCount, " and limit is ", this.clickLimit);
    };

  }]).
factory('notify', ['$window','$log', '$timeout', function(win,$log, $timeout) {
    var msgs = [];
    var clickCounter = 0;
    var countLimit = 0;

    $timeout( function(){
      countLimit = Math.floor(Math.random() * 10)+1;
      $log.debug("[service] Click limit initialized at", countLimit);
      return countLimit;
    }, 10);

    return {
        clickLimit: function(){
          return countLimit;
        },
        clickCount: function() {
            clickCounter = msgs.length;
            $log.debug("[service] You are clicking, click count is now", clickCounter, " limit is ", countLimit);
            return clickCounter;
          },
        push: function(msg) {
              msgs.push(msg);
              clickCounter = msgs.length;
              $log.debug("[service] Counter is", clickCounter, " on ", countLimit);
              if (msgs.length === countLimit) {
                win.alert(msgs.join('\n'));
                msgs = [];
              }
            }
      }
  }]);
})(window.angular);

pen

中的工作示例

1 个答案:

答案 0 :(得分:0)

之所以无法按预期运行,是因为countLimit是一个基元,并且基元总是通过byVal而不是byRef传递,因此工厂无法在以下位置更新值:以后。

countLimit更改为对象可以解决此问题,因为对象的值是对对象属性的引用。换句话说,我们能够传递byRef。我们只需要更新代码即可引用该对象的子属性,而不是直接引用该值,即countLimit.value

工作示例:https://codepen.io/anon/pen/VVmdbE?editors=1111

(function(angular) {
  'use strict';
  angular.
  module('myServiceModule', []).
  controller('MyController', ['$scope', 'notify', '$log', function($scope, notify, $log) {
    this.clickCount = 0;
    this.clickLimit = notify.clickLimit();
    this.callNotify = function(msg) {
      notify.push(msg);
      this.clickCount = notify.clickCount();
      $log.debug("[controller] Click count is now", this.clickCount, " and limit is ", this.clickLimit.value);
    };

  }]).
  factory('notify', ['$window', '$log', '$timeout', function(win, $log, $timeout) {
    var msgs = [];
    var clickCounter = 0;
    var countLimit = {
      value: 0,
    };

    $timeout(function() {
      countLimit.value = Math.floor(Math.random() * 10) + 1;
      $log.debug("[service] Click limit initialized at", countLimit.value);
      return countLimit;
    }, 10);

    return {
      clickLimit: function() {
        $log.debug("called clickLimit");
        return countLimit;
      },
      clickCount: function() {
        clickCounter = msgs.length;
        $log.debug("[service] You are clicking, click count is now", clickCounter, " limit is ", countLimit);
        return clickCounter;
      },
      push: function(msg) {
        msgs.push(msg);
        clickCounter = msgs.length;
        $log.debug("[service] Counter is", clickCounter, " on ", countLimit);
        if (msgs.length === countLimit.value) {
          win.alert(msgs.join('\n'));
          msgs = [];
        }
      }
    }
  }]);
})(window.angular);
<!doctype html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>Example - example-services-usage-production</title>


  <script src="https://code.angularjs.org/snapshot/angular.min.js"></script>
  <script src="script.js"></script>



</head>

<body ng-app="myServiceModule">
  <div id="simple" ng-controller="MyController as self">
    <p>Let's try this simple notify service, injected into the controller...</p>
    <input ng-init="message='test'" ng-model="message">
    <button ng-click="self.callNotify(message);">NOTIFY</button>
    <p>(you have to click {{self.clickLimit.value-self.clickCount}} times more to see an alert)</p>
    <div>You have clicked {{ self.clickCount }} times</div>
  </div>

</body>

</html>