2014-08-29 3 views
1

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

Так вот моя попытка это -

завод я создал фабрику, чтобы позвонить все 3 входа и их значению по умолчанию (я посылаю их по отдельности, я не могу изменить это сейчас). Это выглядит так:

.factory("getDefaults", function() { 

return { 
    instructions: function() { 
     $http({ 
     method: "GET", 
     url: "/getStringDropdown/materials" 
    }) 
    .success(function(data, status, headers, config){ 
     $scope.instructions.materials = data.text; 
    }); 

    $http({ 
     method: "GET", 
     url: "/getStringDropdown/reinforce" 
    }) 
    .success(function(data, status, headers, config){ 
     $scope.reinforce = data.options; 
     $scope.instructions.reinforce = $scope.reinforce[data.default]; 
    }); 

    $http({ 
     method: "GET", 
     url: "/getStringDropdown/procedure" 
    }) 
    .success(function(data, status, headers, config){ 
     $scope.procedures = data.options; 
     $scope.instructions.procedures = $scope.procedures[data.default]; 
    }); 
    //return data here? 

    } 
    }; 

}) 

Мой вопрос здесь - мне нужно вернуть данные здесь? А также я могу определить области, которые используются здесь (как указано в фактическом контроллере). Я почти уверен, что это неправильно, но я не могу найти хороший пример того, как правильно структурировать что-то подобное.

Звонки в регуляторе,

Так я контроллер моего мышления я бы тогда попробовать что-то вроде этого -

getDefaults.instructions().then(function(){ 
      //possible return data here 
      //AFTER data is flushed out call farm data 

    $http({ 
     method: "GET", 
     url: "/getSavedFormData/formID" 
    }) 
    .success(function(data, status, headers, config){ 
     $scope.instructions.materials= data.materials; 
     $scope.instructions.procedures = $scope.procedures[data.procedure]; 
     $scope.instructions.reinforce = $scope.reinfoce[data.reinforcement]; 
    }); 

     }); 

Так большая картина - Я пытаюсь получить эти 3 вызова в запустить и заполнить, а затем второй. Я не уверен, что может быть или не быть лучшим подходом, фабрика, похоже, имела смысл, основываясь на попытке объединить 3 вызова в одно место с обещанием, когда все будет сделано. Я думаю, мне нужно вернуть данные, но было бы неплохо, если бы я мог определить области для контроллера на заводе. Я все еще получаю свою опору с угловатой, поэтому любое/все указания будут высоко оценены. Спасибо за прочтение!!

+1

Вы пробовали использовать $ q.all() ? (например, здесь: http://fdietz.github.io/recipes-with-angular-js/consuming-external-services/deferred-and-promise.html) –

ответ

3

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

Возможно, вы действительно хотите получить обещание $ http от своей службы, чтобы ваш обратный вызов .success() действительно мог устанавливать модели в $ scope через закрытие (находясь внутри контроллера).

Так что ваш завод будет больше, как это:

.factory("getDefaults", function() { 
    return { 
    instructions: $http({ method: "GET", url: "/getStringDropdown/materials" }) 
    } 
}); 

Если вы действительно думаете, что вы никогда не будете нуждаться в тех, HTTP называет отдельно и вы заботитесь только о том, когда они все решительность. Вы можете вернуть $ q.все() обещание, которое будет решать, когда все они решают:

.factory("getDefaults", function($http, $q) { 
    var promise1 = $http({ method: "GET", url: "/getStringDropdown/materials" }); 
    var promise2 = $http({ method: "GET", url: "/getStringDropdown/materials" }); 
    var promise3 = $http({ method: "GET", url: "/getStringDropdown/materials" }); 
    return { 
    data: $q.all([promise1,promise2,promise3]), 
    anotherCall: $http.get('/anothercallUrl') 
    } 
}); 

Так что теперь от контроллера вы можете просто сделать:

function myCtrl($scope,getDefaults){ 
    getDefaults.data.then(function(data){ 
    //access all three of your promises, their data, and set $scope models here 
    getDefaults.anotherCall.success(function(data){ 
     //or another http call 
    }); 
    }; 
} 

$ q.all документацию здесь: https://docs.angularjs.org/api/ng/service/$q

+0

Это замечательно, спасибо за помощь. Есть ли способ сделать что-то вроде другого. Затем, после того, как я установил области, чтобы вызвать последний $ http? – ajmajmajma

+0

Конечно, вы можете просто сделать другой служебный вызов, который возвращает другое обещание. getDefaults.anotherCall.success (функция (данные) {})); – tommybananas

+0

обновленный ответ выше – tommybananas

1

Использование областей на заводах не является хорошей идеей, мое предложение не использовать, о множественных HTTP вызовов, которые вы должны использовать $q.all

пример здесь в fiddle

для каждого вызов, вы должны создать defered объекта толкать его в массиве затем использовать

$q.all(deferesArray).then(
     function(resp){ 
     // all requests are resolver , resp is array with resolved datas 
     } 
) 
1

Вы можете хотите посмотреть на угловые q $ (https://docs.angularjs.org/api/ng/service/ $ q)

1.) Создайте первые три обещания, которые должны заканчиваться «первым»

var deferred = $q.defer(); 
$http({ 
    method: "GET", 
    url: "/getStringDropdown/procedure" 
}) 
.success(function(data, status, headers, config){ 
    deferred.resolve(data); 
}); 
var promise1 = deferred.promise; 

2.) Используйте весь метод Q $, то называют «то» в результате выполнить вторую часть вашей логики

q$.all([promise1, promise2, promise3]) 
.then(function(results) { 
$http({ 
    method: "GET", 
    url: "/getSavedFormData/formID" 
    }) 
    .success(function(data, status, headers, config){ 
    $scope.instructions.materials= data.materials; 
    $scope.instructions.procedures = $scope.procedures[data.procedure]; 
    $scope.instructions.reinforce = $scope.reinfoce[data.reinforcement]; 
}); 
}); 
+0

Хорошо, это выглядит потрясающе. Где в этом случае я помещаю данные в первые 3 области? Например - дебютный вызов, который вы показали с помощью процедур, мне нужно использовать данные для этого \t $ scope.procedures = data.options; $ scope.instructions.procedures = $ scope.procedures [data.default] ;. Где я могу это разместить? Благодаря!! – ajmajmajma

+0

Параметр «результаты», полученный обещанием, содержит массив объектов результата в порядке выполнения первых 3 обещаний. Таким образом, $ scope.procedures = results [2] .options; например... – alpinescrambler

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