javascript - AngularJs - "deferred"或 "batched"指令

标签 javascript angularjs angularjs-directive

我知道您可能会说的第一句话是“您尝试过什么”,但我能给出的唯一答案是“谷歌”或“书籍”。不幸的是这里没有代码。

我想要实现的目标如下:

1 - 创建一个带有 2 个参数的指令,如下所示

<resource resource-area="AREA" resource-key="KEY" />

2 - 在编译期间,不要直接更改输出,而是将请求的“资源”指令(或其相关对象,例如元素、属性)放入 $scope 中的临时“批处理”中。

3 - 一旦指令所在 View 的编译完成(或接近完成?),那么所有指令最终都会被编译

这样做的目的是只对所有指令进行一次 ajax 调用,而不是针对每个指令进行一次调用。

我希望这是有道理的。老实说,我已经尽我所能地浏览了文档和搜索引擎,但找不到答案。当然也可能没有。但我充满希望:)

最佳答案

编辑:在创建下面的概念验证代码后,解决方案略有不同。

如果您将解决方案更改为使用http 拦截器和服务会怎样?

  1. 编译并链接指令
  2. 他们使用结果 promise 来启动 http 请求
  3. http 请求被拦截并存储在服务中
  4. 当所有指令完成工作后,您可以告诉服务启动批量请求服务会按照预先确定的时间间隔启动请求。
<小时/>

新的解决方案不涉及使用http拦截器,因为在测试这个概念时存在循环依赖问题。

您可以在 http://plnkr.co/edit/eCb3wm 看到它正在运行

首先,创建一个服务来保存所有请求并在稍后的时间点触发它们:

app.service('HttpBatch', function($q, $http, $interval) {
  var batch = [];

  // Fires whatever is inside the batch
  // Removes from the batch after firing
  var fireBatch = function() {
    while (batch.length > 0) {
      var batchObj = batch.shift();
      console.log('Firing batchObj: ', batchObj.config);
      // Fire the request and resolve its promise
      // with whatever the http promise resolves to
      batchObj.deferred.resolve($http(batchObj.config));
    }
  };

  // Adds a request object to the list
  // Returns a promise for the request passed
  var addRequest = function(reqConfig) {
    var deferred = $q.defer();
    batch.push({
      config: reqConfig,
      deferred: deferred
    });
    return deferred.promise;
  };

  // Fires every 3s
  // Feel free to change the interval to what makes most sense for you
  $interval(fireBatch, 3000);

  return addRequest;
});

然后,在指令中使用它而不是 $http。
为了展示如何使用它,下面是一个使用批处理服务发出请求的示例指令。

app.directive('fireReq', function(HttpBatch) {
  return {
    scope: {},
    link: function(scope, el, attrs) {
      var me = 'Directive ' + attrs['fireReq'];
      console.log(me);
      // Example url only
      // Pass a config object just as when using $http
      // Returns a promise
      HttpBatch({
        method:'GET',
        url:'http://run.plnkr.co/user/' + attrs['fireReq']
      }).then(function onSuccess (res) {
        console.log(me + ' got success response: ', res);
      }, function onFailure (res) {
        console.log(me + ' got failure response: ', res);
      });
    }
  };
});

整个解决方案广泛使用了 $q 和 Promise,因此在尝试理解上述代码的工作原理之前,您应该了解它们。

此外,请注意,在生产中使用代码之前,您应该向代码添加一些测试。

我希望这对您的具体情况有所帮助。不过,对我来说学习是个好主意:)

关于javascript - AngularJs - "deferred"或 "batched"指令,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23151165/

相关文章:

javascript - 指令隔离范围 1.2.2

javascript - Jquery Masking 返回 Float/Int 值

javascript - 访问子gridview时如何获取父gridview某一单元格的值?

javascript - jquery如何处理分层SVG对象中的mouseover或mouseenter事件?

javascript - 如何使用 AngularJS 计算列的总重量

javascript - Angular 表达式没有返回任何内容

javascript - 如何重复 123 1231 直到长度目标

javascript - AngularJS 更改 css 属性值

angularjs - Angular 指令 - 在链接方法中定义的模板函数的属性中调用函数时出现插值问题

javascript - 使用 ng-model 将数组中的选择列表发布到服务器