2016-03-09 70 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