5

我有一个 Angularjs 指令“ExampleDirective”,它有控制器“ExampleController”。控制器定义了两个 Promise 对象,每个 Promise 对象发出一个 Http GET 请求并返回响应。

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

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

控制器:

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
    });
  }
 };
}
4

2 回答 2

4

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

第二种解决方案,在指令中使用服务,并始终返回相同的承诺:

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

    return {
        getData: getData
    };
});
于 2016-03-09T20:53:51.447 回答
1

控制器定义了两个 Promise 对象,每个 Promise 对象发出一个 Http GET 请求并返回响应。

改成:

SERVICE定义了两个 Promise 对象,其中每个 Promise 对象发出 Http GET 请求并返回响应。

然后服务可以记住它已经完成了 GET(s),并在以后每次请求它们时返回它们的结果。

于 2016-03-09T20:52:10.657 回答