Повторное использование / рефакторинг кода внутри службы Angular

#javascript #json #angularjs

#javascript #json #angularjs

Вопрос:

У меня есть служба Angular, которая получает данные с помощью запросов JSON и отправляет результирующие объекты JSON на несколько разных контроллеров.

Приведенный ниже код является фрагментом этого сервиса. postData Функция является примером одной из многих различных функций внутри этой службы (которые все в значительной степени выполняют одно и то же, но просто выполняют разные запросы). В этой службе есть другие функции с именами viewData , visitorData и т.д…

 // Service for making JSON requests
    myApp.factory('getData', ['$http', '$cookieStore', 
      function($http, $cookieStore) {
      return {
        postData: function() {

          // Store shared variables   
          var source = 
            ($cookieStore.get('tab') == '#/dashboard/2') ?
            source = $cookieStore.get('1234') :
            source = $cookieStore.get('5678');
          var month = $cookieStore.get('month'),
              year = $cookieStore.get('year');

          // Derive the number of days in the given month
          var month_days = (new Date(year, month, 0)).getDate();

          // Return the promise
          return $http({
            url: base_url   'string', 
            method: "GET",

            // Set the proper parameters
            params: { 
              id: source,
              start: year   '-'   month   '-01',
              end: year   '-'   month   '-'   month_days,
              interval: 'day'
              }
          });
        },
        ...
  

Проблема, с которой я сталкиваюсь, заключается в том, что в начале каждой из этих функций я должен включать этот фрагмент кода, и он точно такой же для каждой функции.

 // Store shared variables   
var source = 
  ($cookieStore.get('tab') == '#/dashboard/2') ?
  source = $cookieStore.get('1234') :
  source = $cookieStore.get('5678');
var month = $cookieStore.get('month'),
    year = $cookieStore.get('year');

// Derive the number of days in the given month
var month_days = (new Date(year, month, 0)).getDate();
  

Однако сложно просто учесть это, потому что, если я это сделаю, при вызове функций source , month и year значения не изменятся вместе с обновленными $cookieStore значениями. Есть ли официальный способ, которым я могу использовать несколько функций в общем ресурсе службы, возможно, суперфункцию, которая вызывается каждый раз, когда вызываются сами функции? В принципе — каков угловой способ справиться с этим?

Ответ №1:

Я не уверен, что это то, к чему вы стремитесь, но вы могли бы инкапсулировать свою логику в другой сервис и включить ее в сервисы, которые вы хотите, чтобы она использовалась в зависимостях;

 myApp.factory('getCookieDataSvc', [ '$cookieStore',function($cookieStore){
return {
    getCookieData: function(){
        var source =
            ($cookieStore.get('tab') == '#/dashboard/2') ?
                source = $cookieStore.get('1234') :
                source = $cookieStore.get('5678');
        var month = $cookieStore.get('month'),
            year = $cookieStore.get('year');

        // Derive the number of days in the given month
        var month_days = (new Date(year, month, 0)).getDate();

        return {
            source: source,
            month_days: month_days,
            month: month,
            year: year,
        }
    }
}
});
  

Затем вы могли бы вызвать его в других своих службах или контроллерах следующим образом:

 myApp.factory('getData', ['$http', 'getCookieDataSvc', function($http, getCookieDataSvc) {
return {
    postData: function() {
        var cookieData = getCookieDataSvc.getCookieData();

        // Return the promise
        return $http({
            url: base_url   'string',
            method: "GET",

            // Set the proper parameters
            params: {
                id: cookieData.source,
                start: cookieData.year   '-'   cookieData.month   '-01',
                end: cookieData.year   '-'   cookieData.month   '-'   cookieData.month_days,
                interval: 'day'
            }
        });
    }
}});
  

Комментарии:

1. Да, я пробовал что-то подобное, но это не сработало. Я собираюсь попробовать это снова.

Ответ №2:

Сделайте их переменными уровня модуля и используйте 'this' для доступа к ним. Пример ниже. Вместо Angular это более модульный способ JavaScript для этого.

 myApp.factory('getData', ['$http', '$cookieStore', 
      function($http, $cookieStore) {
      var factory = {};
      factory.month = ""; // initialize to whatever you want
      factory.year = ""; // initialize to whatever you want

      factory.postData = function() {
           var self = this;
           self.month = $cookieStore.get('month');
           ...
      };

      ...
      ...

      return factory;
}]);
  

Ответ №3:

Если значения в ваших файлах cookie изменчивы, вы также можете организовать свой код таким образом, чтобы всегда получать последние значения из $ CookieStore. Это также позволит вам содержать ваш $cookieStore код в одной функции.

 myApp.factory('getData', ['$http', '$cookieStore', 
  function($http, $cookieStore) {

      function getSource() {
        return (getCookieValue('tab') === '#/dashboard/2')
          ? getCookieValue('1234')
          : getCookieValue('5678')
      }

      function getCookieValue(key) {
        return $cookieStore.get(key);
      }

      // Danger ahead, mutations!
      function initValues(source, month, year) {
        source = getSource();
        month = getCookieValue('month');
        year = getCookieValue('year');
      }

      return {
        postData: function() {

          // Store shared variables   
          var source, month, year;
          initValues(source, month, year);

          // Derive the number of days in the given month
          var month_days = (new Date(year, month, 0)).getDate();

          // Return the promise
          return $http({
            url: base_url   'string', 
            method: "GET",

            // Set the proper parameters
            params: { 
              id: source,
              start: year   '-'   month   '-01',
              end: year   '-'   month   '-'   month_days,
              interval: 'day'
              }
          });
        },
        ...