2016-03-09 30 views
4

我有一个Angularjs指令'ExampleDirective',它具有控制器'ExampleController'。控制器定义了两个Promise对象,其中每个Promise对象发出一个Http GET请求并返回响应。AngularJS - 多个指令实例使XHR调用多次

在指令中,我们从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请求两次?

UPDATE 这就是我所做的,我添加了一个服务,如答案中的建议。

服务:

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

服务是** **单身。指令控制器针对指令的每个实例都实例化。在服务中执行XHR以避免重复。 – georgeawg

+0

谢谢@georgeawg – nmusleh

回答

3

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

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

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

    return { 
     getData: getData 
    }; 
}); 
+0

谢谢你,我编辑了一下,它适合我的角度编程风格。你介意对我的问题进行投票吗? – nmusleh

1

控制器定义了两个对象无极其中每个无极对象 发出HTTP GET请求,并返回响应。

更改为:

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

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

+0

谢谢。你的回答有帮助。 – nmusleh