2016-03-09 7 views
4

У меня есть директива Angularjs 'ExampleDirective', которая имеет контроллер 'ExampleController'. Контроллер определяет два объекта Promise, где каждый объект Promise выполняет запрос Http GET и возвращает ответ.AngularJS - Несколько директив Экземпляры, делающие вызов XHR несколько раз

В директиве мы получаем данные ответа от объектов обещания и обрабатываем их для визуализации директивы.

ПримерDirective получает экземпляр дважды в одном представлении, и каждый экземпляр делает его собственные запросы 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 
    }); 
    } 
}; 
} 
+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

Контроллер определяет два объекта Promise, где каждый объект Promise делает запрос HTTP GET и возвращает ответ.

Изменить на:

SERVICE определяет два Promise объектов, где каждый объект Promise делает запрос HTTP GET и возвращает ответ.

Служба затем может помнить, что она уже сделала GET (ы) и просто возвращает их результат каждый последующий запрос.

+0

спасибо. Ваш ответ помог. – nmusleh

 Смежные вопросы

  • Нет связанных вопросов^_^