Naprawdę nie podoba mi się fakt, że z powodu „obiecującego” sposobu robienia rzeczy konsument usługi korzystającej z $ http musi „wiedzieć”, jak rozpakować odpowiedź.
Chcę tylko zadzwonić i pobrać dane, podobnie jak w starym $scope.items = Data.getData();
sposobie, który jest już przestarzały .
Próbowałem przez chwilę i nie znalazłem idealnego rozwiązania, ale oto mój najlepszy strzał ( Plunker ). Może być komuś przydatny.
app.factory('myService', function($http) {
var _data; // cache data rather than promise
var myService = {};
myService.getData = function(obj) {
if(!_data) {
$http.get('test.json').then(function(result){
_data = result.data;
console.log(_data); // prove that it executes once
angular.extend(obj, _data);
});
} else {
angular.extend(obj, _data);
}
};
return myService;
});
Następnie kontroler:
app.controller('MainCtrl', function( myService,$scope) {
$scope.clearData = function() {
$scope.data = Object.create(null);
};
$scope.getData = function() {
$scope.clearData(); // also important: need to prepare input to getData as an object
myService.getData($scope.data); // **important bit** pass in object you want to augment
};
});
Są wady, które już dostrzegam
- Musisz przekazać obiekt, do którego chcesz dodać dane , co nie jest intuicyjnym ani powszechnym wzorcem w Angular
getData
może zaakceptować obj
parametr tylko w postaci obiektu (chociaż może również zaakceptować tablicę), co nie będzie problemem dla wielu aplikacji, ale jest to bolesne ograniczenie
- Trzeba przygotować obiekt wejściowy
$scope.data
z = {}
aby uczynić go przedmiotem (w zasadzie to, co $scope.clearData()
robi powyżej), lub = []
na tablicy, czy to nie będzie działać (mamy już konieczności zakładają coś o jakie dane nadchodzi). Próbowałem wykonać ten krok przygotowawczy IN getData
, ale bez powodzenia.
Niemniej jednak zapewnia wzorzec, który usuwa płytę kontrolną „obiecaj rozpakuj” i może być przydatny w przypadkach, gdy chcesz użyć pewnych danych uzyskanych z $ http w więcej niż jednym miejscu, zachowując jednocześnie SUCHOŚĆ.
then
?