来自异步服务的 Angularjs 绑定值 [英] Angularjs binding value from async service

查看:20
本文介绍了来自异步服务的 Angularjs 绑定值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

感谢@sehaxx 在Angularjs binding value from 中解决了几个错误服务 我想在示例中引入异步,如下面的代码,其中一个变量是异步初始化的,它的值没有反映在视图中.

(函数(角度){'使用严格';棱角分明.模块('myServiceModule',[]).控制器('MyController', ['$scope', 'notify','$log', function($scope, notify, $log) {this.clickCount = 0;this.clickLimit = notify.clickLimit();this.callNotify = 函数(味精){通知.推(味精);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;$超时(函数(){countLimit = Math.floor(Math.random() * 10)+1;$log.debug("[service] 点击限制初始化于", countLimit);返回计数限制;}, 10);返回 {点击限制:功能(){返回计数限制;},单击计数:函数(){clickCounter = msgs.length;$log.debug("[service] 你正在点击,点击计数是现在", clickCounter, " limit is ", countLimit);返回点击计数器;},推:功能(味精){msgs.push(msg);clickCounter = msgs.length;$log.debug("[service] Counter is", clickCounter, " on ", countLimit);if (msgs.length === countLimit) {win.alert(msgs.join('\n'));消息 = [];}}}}]);})(window.angular);

pen

中的工作示例

解决方案

之所以没有按预期工作是因为 countLimit 是一个 Primitive,而 Primitives 总是通过Val 传递而不是 byRef,因此工厂无法在以后更新该值.

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

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

(function(angular) {'使用严格';棱角分明.模块('myServiceModule',[]).控制器('MyController', ['$scope', 'notify', '$log', function($scope, notify, $log) {this.clickCount = 0;this.clickLimit = notify.clickLimit();this.callNotify = 函数(味精){通知.推(味精);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 = {值:0,};$超时(功能(){countLimit.value = Math.floor(Math.random() * 10) + 1;$log.debug("[service] 点击限制初始化于", countLimit.value);返回计数限制;}, 10);返回 {点击限制:函数(){$log.debug("调用clickLimit");返回计数限制;},单击计数:函数(){clickCounter = msgs.length;$log.debug("[service] 你正在点击,点击计数是现在", clickCounter, " limit is ", countLimit);返回点击计数器;},推:功能(味精){msgs.push(msg);clickCounter = msgs.length;$log.debug("[service] Counter is", clickCounter, " on ", countLimit);if (msgs.length === countLimit.value) {win.alert(msgs.join('\n'));消息 = [];}}}}]);})(window.angular);

<html lang="zh-cn"><头><meta charset="UTF-8"><title>示例 - example-services-usage-production</title><script src="https://code.angularjs.org/snapshot/angular.min.js"></script><script src="script.js"></script><body ng-app="myServiceModule"><div id="simple" ng-controller="MyController as self"><p>让我们试试这个简单的通知服务,注入控制器...</p><input ng-init="message='test'" ng-model="message"><button ng-click="self.callNotify(message);">NOTIFY</button><p>(您必须再点击 {{self.clickLimit.value-self.clickCount}} 次才能看到警报)</p><div>您点击了 {{ self.clickCount }} 次</div>

</html>

Having resolved a couple of errors thanks to @sehaxx in Angularjs binding value from service I would like introduce async in the example as in the following code where a variable is initialized asynchronously and it's value is not reflected in the view.

(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);

Working example in pen

解决方案

The reason this isn't working as expected is due to the fact that countLimit is a Primitive, and Primitives are always passed byVal rather than byRef, so there is no way for the factory to update the value at a later date.

Changing the countLimit to an Object fixes this, because the value of the Object is the Reference to the properties of the Object. In other words, we are able to pass byRef. We just have to update our code to refer to the Object's child property instead of referring to the value directly, i.e. countLimit.value.

working example: 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>

这篇关于来自异步服务的 Angularjs 绑定值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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