2014-11-11 4 views
0

При построении сервисного слоя в приложении с угловым я заметил, что много повторений кода для создания обещаний поэтому попыталось сделать общий сервис getPromise, поскольку 90% обещаний - это одна и та же структура.Generic Angular Promise Service

Хотя, возвращая обещание от службы, функция не выполняется в обычном режиме, даже если возвращаемый объект тот же.

Неужели кто-то пытался это сделать? Например.

angular.module('fooApp') 
.service('promise', function promise($q, $http) { 
    return { 
     getPromise: function (url, data) { 

      var deferred = $q.defer(); 

      $http.post(url, data) 
      .success(function (data) { 
       deferred.resolve(data); 
      }) 
      .error(function (error) { 
       deferred.reject(error); 
      }); 

      return deferred.promise; 
     } 
    }; 
}) 

.service('foo', function foo(config, promise) { 
    return { 
     getFoo: function (userId) { 
      var deferred = $q.defer(); 
      var url = config.svcUser + 'GetFoo'; 
      var data { 
       userId: userId 
      }; 

      $http.post(url, data) 
      .success(function (data) { 
       deferred.resolve(data); 
      }) 
      .error(function (error) { 
       deferred.reject(error); 
      }); 

      return deferred.promise; 
     }, 
     getFoo2: function (userId) { 
      var url = config.svcUser + 'GetFoo'; 
      var data { 
       userId: userId 
      }; 
      return promise.getPromise(url, data); 
     } 
    } 
}) 


.controller('AgenciesCtrl', function ($scope, agency) { 

    agency.getFoo().then(function (agencies) { 
     // does fire 
    }); 

    agency.getFoo2().then(function (foo) { 
     // does not fire 
    }); 

    $scope.loadAgency = function (agencyId) { 
     agency.getFullAgencyProfile(agencyId).then(function (agency) { 
      $scope.agency = agency; 
     }); 
    } 

}); 

вопрос кажется довольно легким в этом маленьком примере, но я планирую по реализации 30+ услуг, с тем, что позволит сократить повторения кода много, если это возможно.

+1

Я вижу это все время, как сказал @MaxFichtelmann '$ http.post' возвращает обещание, нет необходимости, чтобы обернуть его с' $ q' I» Я не знаю, почему люди этого не понимают. Также хорошая идея с сервисом обернуть код X с обещанием, но вы уже можете сделать это с помощью '$ q.when (...) '= * Обертывает объект, который может быть значением или (сторонним), тогда можно обещать в обещание $ q * –

+0

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

ответ

-1

Вот что я обычно делаю

В вызове метода обслуживания:

return $http.post(url,data,{}) 
    .success(function(response){ 
     return response.data; 
    }) 
    .error(function(response){ 
     // return error/status code 
    }); // end $http.post 

Тогда в контроллере:

var data = someSrvc.methodCall(); 

// you could also follow this up with 
$q.when(data).then(...); 

Или

В службе:

return $http.post(url,data,{}); 

Затем контроллер (или где-либо):

someSrvc.methodCall().then(function(response){ 
    // some success code 
},function(response){ 
    // some error code 
}); // end methodCall 

$ q.when сделать что-то в пример обещание:

$q.when((someVal <= 0) && (someOtherVal > 0)) 
    .then(function(){ 
     // do something when condition is true 
    }); 

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

while(myArray1.length > 0) 
    myArray1.pop(); 

while(myArray2.length > 0) 
    myArray2.pop(); 

$q.when((myArray1.length <= 0) && (myArray2.length <= 0)).then(function(){ 
    // do something 
}); 
+0

Спасибо, это здорово. Я не знал, что $ http дает обещание. Я довольно новичок в Angular, поэтому такая информация действительно полезна. – JamesEddyEdwards

+0

@JamesEddyEdwards рады помочь –

+2

Это полный плохих советов, 'success' не цепочка (он возвращает то же самое обещание) - ваше использование' $ q.when' бессмысленно, рискованно и deferrs без причины (нет смысла в делая async, когда это не требуется, это просто медленно и запутанно), вы также делаете '$ q.when' без уважительной причины в вещах, которые уже обещаны. –

0

Вы правы! Ваш код повторяется - это называется the deferred anti-pattern.

Обещает абстрактные значения, которые являются временными - то есть: они еще недоступны. Так же, как ваш код, как правило, цепочки (одна строка после следующей), так что обещают с then.

Угловые обещания, как и обещает + предлагают довольно современную реализацию и все Угловое делает асинхронно и логически операции один раз уже возвращает обещание. Это включает в себя все $ http, а также $ timeout, $ resource и так далее.

Ваш код может быть гораздо проще:

angular.module('fooApp')  
.service('foo', function foo(config, promise) { 
    return { 
     getFoo: function (userId) { 
      var url = config.svcUser + 'GetFoo'; 
      var data { userId: userId }; 
      return $http.post(url, data).then(function(resp){ 
       // any validations you need on the response go here 
       return response.data; 
      }); 
     } 
    } 
}).controller('AgenciesCtrl', function ($scope, foo) { 
    foo.getFoo().then(function (agencies) { 
     // does fire, and schedules a digest because it's an Angular promise 
     $scope.someVar = agencies; // safe to do here, since a digest will happen 
    }); 
}); 
+0

Спасибо, Бен, я действительно смог дойти до этого момента, посмотрев обещание, возвращенное из функции $ http Angular в деталях. Когда вы упоминаете // какие-либо проверки ... вы предполагаете, что это может повлиять на ответ об ошибке/успехе на основе возвращаемого объекта? Это была проблема, с которой я тогда столкнулся. Я знаю, в идеале ответ всегда будет успешным, но это не всегда относится к API, с которым я работаю. Я должен сделать некоторую проверку на ответ, чтобы управлять возвращенным состоянием (следовательно, почему Q. обещал, казалось, хорошее решение раньше). – JamesEddyEdwards

+0

Любая дополнительная информация была бы замечательной и благодарит вас за то, что вы прояснили выше, оцените ее! – JamesEddyEdwards

+0

Несомненно - это именно то, что я имел в виду с '// любой валидацией'. если вы считаете, что мой ответ решил вашу проблему, подумайте о принятии его (не чувствуйте давления, хотя). –

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