AngularJS - 多个指令实例多次进行 XHR 调用

AngularJS - Multiple Directive Instances making XHR call multiple times

我有一个 Angularjs 指令 'ExampleDirective',它有控制器 'ExampleController'。控制器定义了两个 Promise 对象,其中每个 Promise 对象发出一个 Http GET 请求和 returns 响应。

在指令中,我们从 promise 对象中获取响应数据并处理它们以呈现指令。

ExampleDirective 在同一视图中被实例化两次,每个实例都发出自己的 Http GET 请求。由于同时发送两个请求以进行昂贵的数据库调用并从同一个 table 读取,这会导致前端出现性能问题。

控制器:

angular.module('exampleModule')
  .constant("EXAMPLE_URL", "{% url 'example:get_example' %}")
  .controller('exampleCtrl', ['$scope', '$http', 'EXAMPLE_URL', exampleCtrl]);

function exampleCtrl($scope, $http, EXAMPLE_URL) {
  $scope.examplePromise = $http.get(EXAMPLE_URL).then(function(response) {
    return response.data;
  });
}

指令:

angular.module('exampleModule')
.directive('exampleDirective', ['exampleFactory', 'STATIC_URL',      '$http', '$window', exampleDirective]);

function exampleDirective(exampleFactory, STATIC_URL, $http, $window) {
  return {
    scope: {
      title:'@?',
      loadingImage:'@?',
    },
    restrict: 'AE',
    templateUrl: STATIC_URL + 'example/example-template.html',
    controller: "exampleCtrl",

    link: function (scope, element, attrs) {

     //add default options:
    if (!scope.title) {
      scope.title = 'Example Title';
    }
    if (!scope.loadingImage) {
      scope.loadingImage = '';
    }

    scope.examplePromise.then(function(data) {
      scope.exampleData = data;
      // do something
    });
  }
 };
}

有没有办法多次实例化指令,而不必在控制器中发出两次 Http GET 请求?

更新 这就是我所做的,我按照答案中的建议添加了一项服务。

服务:

angular.module('chRatingsModule')
.factory('chExampleFactory', ['$http', 'EXAMPLE_URL', chExampleFactory]);

function chExampleFactory($http, EXAMPLE_URL) {
  var api = {}
  var promise = null;
  api.examplePromise = examplePromise; 

  function examplePromise() {
    if (promise == null) {
      promise = $http.get(EXAMPLE_URL).then(function(response) {
        return response.data;
      });
    }
    return promise;
  }

  return api;
}

更新指令:

angular.module('exampleModule')
.directive('exampleDirective', ['exampleFactory', 'STATIC_URL',      '$http', '$window', exampleDirective]);

function exampleDirective(exampleFactory, STATIC_URL, $http, $window) {
  return {
    scope: {
      title:'@?',
      loadingImage:'@?',
    },
    restrict: 'AE',
    templateUrl: STATIC_URL + 'example/example-template.html',

    link: function (scope, element, attrs) {

    exampleFactory.examplePromise.then(function(data) {
      scope.exampleData = data;
      // do something
    });
  }
 };
}

The controller defines two Promise objects where each Promise object makes an Http GET request and returns the response.

更改为:

The SERVICE defines two Promise objects where each Promise object makes an Http GET request and returns the response.

服务然后可以记住它已经完成了 GET(s) 并且只是 return 他们的结果每次被要求时。

第一个解决方案,可能是最好的解决方案:不要从指令进行调用,它应该只是一个图形元素。从控制器进行调用,并将数据作为参数传递给两个指令。

第二种解决方案,在指令中使用一个服务,并且总是return相同的承诺:

myModule.factory('myService', function($http) {
    var promise = null;
    var getData = function() {
        if (promise == null) {
            promise = $http.get(...).then(...);
        }
        return promise;
    };

    return {
        getData: getData
    };
});