2015-10-01 2 views
1

У меня есть пара вопросов по асинхронным функциям в угловом. Я хочу, чтобы моя служебная функция могла возвращать данные, получаемые с помощью $ http, и использовать эти данные в другой функции. Позвольте мне продемонстрировать с текущим кодом:асинхронные вызовы в angularjs

dashboard.servicesModule.service('SubscriptionService', function ($http, $q) { 

    this.getImportantData= function (param1, param2) { 

     var url = "my/url/with/parameters?param1=param1&param2=param2";  

     $http.get(url).then(function(response){   
      console.log("response"); 
      console.log(response.data); // < --- this actually shows the data i need!!   
      return response.data.vsyData; <--- however, this returns undefined 
     }, function(error){ 
      // some error thingy just in case 
     }); 

    }; 

    this.getSomeFunctionality = function(param1, param2, param3){ 
     var importantdata= this.getImportantData(param1, param2); 

     // do some filtering on the data with the purpose of returning only what i need 

     console.log(importantdata); <--- undefined 

    }; 

    this.getEvenMoreFunctionality = function(param1, param2, param3){ 
     var importantdata= this.getImportantData(param1, param2); 

     // reusing getImportantData again! 

     console.log(importantdata); <--- undefined 

    }; 
}); 

Так что я пытался все виды вещей (например, this и this) и некоторые изобретения мои собственные. Но начинает казаться, что нет способа использовать данные из $ http.get где-нибудь еще, а затем в своем обратном вызове. И так как мне нужен endresult в моем контроллере, кажется, что нет другого пути, а затем выполнить $ http.get (url) .success (... некоторая логика здесь) в моем контроллере и выполнять фильтрацию и другие манипуляции там.

Однако, я прочитал here и я цитирую:

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

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

Самый важный вопрос: как я могу сделать вышеуказанный код делать то, что он должен делать, или это было бы невозможно?

И должен ли я выполнять свою бизнес-логику в своем контроллере? Потому что here, in the angular docs Я в основном читал, что вы должны вести бизнес-логику в своем контроллере, но не фильтровать ...

Возможно, это очевидно, но ... Я угловатый новичок :-). Спасибо!

+0

Вы не присвоить значение 'dates' в любом месте, так что это явно не определено. – muenchdo

+0

@muenchdo ваши права, я хотел быть слишком быстрым при редактировании кода, чтобы оставить данные, чувствительные к компании.Я собираюсь изменить свой вопрос –

ответ

4

Попробуйте это:

this.getImportantData= function (param1, param2) { 
    var url = "my/url/with/parameters?param1=param1&param2=param2";  

    return $http.get(url); 
}; 

this.getSomeFunctionality = function(param1, param2, param3){ 
    this.getImportantData(param1, param2) 
    .then(function(response){   
     console.log(response.data.vsyData); 
    }, function(error){ 
     // some error thingy just in case 
    }); 
}; 

this.getEvenMoreFunctionality = function(param1, param2, param3){ 
    this.getImportantData(param1, param2) 
    .then(function(response){   
     console.log(response.data.vsyData); 
    }, function(error){ 
     // some error thingy just in case 
    }); 
}; 

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

+0

Итак, в основном функция getSomeFunctionality не может вернуть конечный результат (например, некоторую математическую проверку и фильтрацию данных) моему контроллеру? Я могу фильтровать внутри .then (function (response) {}, но я не могу вернуть результат на мой контроллер? Если это так, нет смысла ставить эту логику в отдельную услугу, которую я предполагаю? –

2

Для assyncronous запроса вы не можете сделать оператор возврата imediate, основная часть javascript не будет ждать разрешения запроса. Я действительно рекомендую использовать $q API, это угловая реализация обещаний/отложенных систем Криса Коваля.

function getSomething(){ 
    var deferred = $q.defer(); 
    $http.get('foo/bar') 
     .success(function(data){ 
      $deferred.resolve(data); 
     }); 
    return deferred.promise(); 
} 

getSomething().then(function(data){ 
    console.log(data); 
}); 

Или вы можете вернуться непосредственно $http обещание. Если вы хотите удалить .then() со своего контроллера, вы можете использовать $routeProvider с опцией resolve, которая поддерживает $q, обещая и создавая маршруты, которые самостоятельно разрешают ваши данные, поэтому вы просто вводите их в контроллер, без проведения процедур $q.

UPDATE 1 - Практический пример разрешения зависимостей в маршрутах

$routeProvider.when('/items/list', { 
    templateUrl: '/templates/item/list', 
    controller: 'ListItemsCtrl', 
    resolve: { 
     items: function(ItemsService) { 
     return ItemsService.getItems(); // getItems returns a promise like 'return $http.get('/items');' 
     } 
    } 
    }); 

//controller 
function ListItemsCtrl($scope, items){ 
    //do something with your items 
} 
+0

Спасибо за обновление! кажется очень полезным для изучения! –

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