AngularJS-多个指令实例多次调用XHR [英] AngularJS - Multiple Directive Instances making XHR call multiple times

查看:99
本文介绍了AngularJS-多个指令实例多次调用XHR的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个Angularjs指令"ExampleDirective",它具有控制器"ExampleController".控制器定义了两个Promise对象,其中每个Promise对象都会发出Http GET请求并返回响应.

I have an Angularjs directive 'ExampleDirective' which has the controller 'ExampleController'. The controller defines two Promise objects where each Promise object makes an Http GET request and returns the response.

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

In the directive, we get the response data from the promise objects and process them to render the directive.

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

ExampleDirective gets instantiated twice within the same view and each instance makes it's own Http GET requests. This causes performance issues on the front end due to two requests sent at the same time to make expensive database calls and read from the same table as well.

控制器:

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请求?

Is there a way to instantiate a directive multiple times but not have to make the Http GET requests in the controller twice?

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

UPDATE This is what I did, I added a service as suggested in the answer.

服务:

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

推荐答案

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

First solution, probably the best one: don't make the call from the directive, which should just be a graphical element. Do the call from the controller, and pass the data as argument to both directives.

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

Second solution, use a service in the directive, and always return the same promise:

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

    return {
        getData: getData
    };
});

这篇关于AngularJS-多个指令实例多次调用XHR的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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