2015-05-20 2 views
-1

У меня есть следующие контроллеры:

angular.module('app').controller('ParentCtrl', function(Service) { 

    var list = [] 
    var init = function() { 
     Service.query().success(function() { 
      list = Service.getList(); 
     }); 
    } 
}); 

angular.module('app').controller('ChildCtrl', function(Service) { 

    var list = [] 
    var init = function() { 
     list = Service.getList(); 
    } 
}); 

angular.module('app').factory('Service', function($http) { 

    list = [] 
    return { 
     query : function() { 
      $http.get('/path/to/my/api').success(function(data){ 
       list = data 
      }) 
     }, 
     getList: function() { 
      return list; 
     } 
    } 
    }); 

Мой HTML выглядит следующим образом:

<div ng-controller="ParentCtrl as parent"> 
    <div ng-controller="ChildCtrl as child"> 

    </div> 
</div> 

Так в основном, когда я получаю запрос AJAX я хочу оба контроллеры для получения обновленных данных

ответ

2

Лучше всего было бы вернуть обещание $http.get:

angular.module('app').factory('Service', function($http) { 
    var promise; 
    return { 
    getList: function() { 
     if (promise) { 
      return promise; 
     } 

     promise = $http.get('/path/to/my/api'); 
     return promise; 
    } 
    } 
}); 

angular.module('app').controller('ParentCtrl', function(Service) {  
    var list = []; 
    var init = function() { 
     Service.getList().then(function(response) { 
      list = response.data; 
     }); 
    } 
}); 

angular.module('app').controller('ChildCtrl', function(Service) { 
    var list = []; 
    var init = function() { 
     Service.getList().then(function(response) { 
      list = response.data; 
     }); 
    } 
}); 
+0

hmm bu это сделало бы дубликат вызова сервера. Я считаю, что целью OP было не выполнение повторяющихся серверных вызовов, поэтому OP имеет два разных метода. – PSL

+0

Да, я обновил свой ответ. –

+0

Да, аналогичная идея. Вероятно, это слишком похоже, немного проще –

1

Вы можете передавать пользовательские сообщения rootScope, и ваши контроллеры получат это сообщение и обработают его.

angular.module('app').controller('ParentCtrl', function($rootScope, $scope, Service) { 

    $scope.list = []; 

    $scope.$on('Service:list', function(event, data){ 
     $scope.list = data; 
    }); 
}); 

angular.module('app').controller('ChildCtrl', function($rootScope, $scope, Service) { 

    $scope.list = []; 

    $scope.$on('Service:list', function(event, data){ 
     $scope.list = data; 
    }); 

    Service.query(); // run once, get in both controllers 
}); 

angular.module('app').factory('Service', function($rootScope, $http) { 
    var list; 

    return { 
     query : function() { 
      $http.get('/path/to/my/api').success(function(data){ 
       list = data; 
       $rootScope.$broadcast('Service:list', list); 
      }) 
     }, 
     getList: function() { 
      return list; 
     } 
    } 
}); 
+0

Хотя это сработает для этого конкретного примера, это может привести к серьезному недостатку дизайна с точки зрения того, кто должен сделать первый вызов и т. Д. IMHORefactoring или создание улучшений может привести к трудностям (по моему опыту), особенно при публикации события из служб не забывайте, что вам нужно вводить '$ rootScope' в службу, что иногда бывает странно. – PSL

+0

Этот ответ для текущего вопроса. Но мне интересно, какие трудности это может сделать, вам нужно публиковать данные через событие - поэтому используйте rootScope, не нужно - поэтому не определяйте его. – num8er

+0

пример: - если у вас есть еще один контроллер-спутник, который использует те же данные, кто должен сделать первый запрос «запрос», чтобы дублировать вызовы не было? Или, если вызов выполняется из разных компонентов (или контроллеров, чтобы просто упростить), кто решает, кто должен делать запрос «запрос» .. Он будет отбрасываться таким образом, что другие компоненты имеют скрытую зависимость от того, кто должен сделать вызов , вот что я имел в виду. – PSL

1

Вы можете обрабатывать его разными способами. Один простой способ - скрыть обещание и вернуть его.

Пример: -

angular.module('app').factory('Service', function($http, $q) { 
    var listPromise; 
    return { 
     getList: function() { 
      //If promise is already present then 
      return listPromise || (listPromise = $http.get('/path/to/my/api').then(function(response){ 
       return response.data; 
      }) 
      //Use the below 2 blocks (catch and finally) only if you need. 
      //Invalidate in case of error 
      .catch(function(error){ 
        listPromise = null; 
        return $q.reject(error); 
      }) 
      //Use finally to clean up promise only if you only need to avoid simultaneous request to the server and do not want to cache the data for ever. 
      .finally(function(){ 
       listPromise = null; 
      })); 
     } 
    } 
    }); 

и в контроллере:

angular.module('app').controller('ParentCtrl', function(Service) { 
    var list = []; 
    var init = function() { 
     Service.getList().then(function(data) { 
      list = data; 
     }); 
    } 
}); 

angular.module('app').controller('ChildCtrl', function(Service) { 

    var list = []; 
    var init = function() { 
     Service.getList().then(function(data) { 
      list = data; 
     }); 
    } 
}); 

Кэширование обещание будет убедиться, что это действительно не имеет значения, кто делает первый звонок, и вы всегда сделать тот же вызов службы для получения данных и обслуживания будет управлять кэшированием данных с помощью обещаний и предотвращать любые повторяющиеся вызовы.

Другая практика заключается в реализации одностороннего потока данных с использованием flux pattern. Где вы создаете магазины, которые хранят данные, и он будет делать ajax-вызов через диспетчера и выдает событие подписчикам события изменения. Существует угловая библиотека (flux-angular), которая также может использоваться для реализации этого шаблона. Это действительно поможет синхронизировать данные между несколькими компонентами, независимо от того, являются ли они родитель/ребенок или братьев и сестер, и независимо от того, кто делает первый звонок и т.д ..

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