AngularJs - " deferred"或者"批量"指示

时间:2014-04-18 09:21:54

标签: javascript angularjs angularjs-directive

我知道你可能会说的第一件事是"你尝试了什么",但我能给出的唯一答案是" google"或"书籍"。很遗憾,这里没有代码。

我想要实现的目标如下:

1 - 创建一个带有2个参数的指令

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

2 - 在编译期间,不是直接改变输出,而是放置所请求的资源&#34;指令(或其相关对象,例如元素,attrs)成为一个临时的&#34;批次&#34;在$ scope。

3 - 一旦编译完成(或接近完成??)对于指令所在的视图,则最终编译所有指令

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

我希望这是有道理的。老实说,我尽我所能在文档和搜索引擎中搜寻,无法找到答案。当然可能没有。但我很有希望:)

1 个答案:

答案 0 :(得分:1)

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

如果您要更改解决方案以使用 http拦截器和服务,该怎么办?

  1. 指令被编译和链接
  2. 他们使用结果承诺启动http请求
  3. http请求获取截获并存储在服务中
  4. 当所有指令完成后,您可以告诉服务激活您的批处理请求该服务会以预先确定的时间间隔触发请求。

  5. 新解决方案不涉及使用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,因此在尝试理解上述代码的工作原理之前,您应该了解它们。

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

    我希望在您的特定情况下帮助您。不过,为我学习是一个不错的主意:)