2016-05-26 8 views
1

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

app.service('WizardService', ['$http', function($http) { 

    var base_url = '/api'; 
    var service = {}; 

    service.postStep1 = function(){ 

     return $http.post(base_url+'/step-1'); 

    }; 

    service.postStep2 = function (data){ 

     return $http.post(base_url+'/step-2', data); 

    }; 

    service.postStep3 = function (data){ 

     return $http.post(base_url+'/step-3', data); 

    }; 

    return service; 

}]); 

Для шага 1 и 2, я хочу использовать InteceptorA и Шаг 3 Я хочу использовать InterceptorB. Каков самый чистый способ сделать это?

ответ

0

Внедрите один перехватчик, как показано на рисунке the documentation for the $http service.

Если вам нужно перехватить запросы в обратном вызове 'requests', проверьте config.url и используйте что-то похожее на соответствие регулярному выражению. Пример:

// register the interceptor as a service 
$provide.factory('myInterceptor', function() { 
    return { 
    'request': function(config) { 
     if (/step-1$/.test(config.url)) doSomething1(); 
     if (/step-2$/.test(config.url)) doSomething2(); 
     if (/step-3$/.test(config.url)) doSomething3(); 
     return config; 
    } 
    } 
} 
+0

Какие причины для этого есть, имея несколько перехватчиков? – Snixtor

+0

Прежде всего, спасибо. Но если у меня есть 100 маршрутов, это не имеет смысла. Как я могу использовать различные перехватчики и назначать их определенным маршрутам? –

1

Какие Гвоздика ответил хорошо, но если есть несколько маршрутов, то это будет трудно назначить несколько if условий на основе URL. Кроме того, если URL-адрес изменяется, вам также нужно изменить в перехватчике.

Я думаю, что самый чистый способ достичь этого - это конфигурация. Давайте начнем с вашей службы:

app.service('WizardService', ['$http', function($http) { 

    var base_url = '/api'; 
    var service = {}; 

    service.postStep1 = function(){ 
     return $http.post(base_url + '/step-3', null, {interceptMe: 'A'}); 
    }; 

    service.postStep2 = function (data){ 
     return $http.post(base_url + '/step-2', null, {interceptMe: 'A'}); 
    }; 

    service.postStep3 = function (data){ 
     return $http.post(base_url + '/step-3', null, {interceptMe: 'B'}); 
    }; 

    service.postStep4 = function (data) { 
     // no interception 
     return $http.post(base_url + '/step-3'); 
    }; 

    return service; 
}]); 

Теперь зарегистрировать перехватчик (я просто показывать вам основную логику перехватчик):

$httpProvider.interceptors.push(['$rootScope', function($rootScope, $q) { 
    return { 
     'request': function (config) { 
      if (config.interceptMe) { 
       if (config.interceptMe === 'A') { 
        // do something for interceptor type a 
       } else if (config.interceptMe === 'B') { 
        // do for type be 
       } 
      } 

      return config; 
     } 
    } 
}); 
0

Во-первых, нет ничего в службе $http и его используйте свойство $httpProvider.interceptors, чтобы выполнить то, что вы ищете.

Ссылаясь на v1.5.6 source.

.interceptors является массив план (строка 375):

var interceptorFactories = this.interceptors = []; 

И они в конечном счете, просто толкнул (или несмещенной) в обещание цепи, в зависимости от того, является ли это запрос или ответ.

Линия 986:

// apply interceptors 
forEach(reversedInterceptors, function(interceptor) { 
    if (interceptor.request || interceptor.requestError) { 
     chain.unshift(interceptor.request, interceptor.requestError); 
    } 
    if (interceptor.response || interceptor.responseError) { 
     chain.push(interceptor.response, interceptor.responseError); 
    } 
}); 

Так, кроме прокатки собственной альтернативы $http услуг (а не то, что я бы рекомендовал в этом случае), вы должны работать в пределах того, что вы может выполнять внутри самого перехватчика http. Другими словами, перехватчик (или перехватчики) должен будет самостоятельно управлять маршрутами фильтрации.

Я вижу 3 несколько разных способа, которыми вы могли бы это сделать.

  1. Единственный перехватчик, который выступает в качестве «маршала» для вызова логики на основе маршрута.
  2. Несколько перехватчиков, каждый со своей собственной логикой фильтрации маршрута.
  3. Несколько перехватчиков с логикой фильтрации с заданной/введенной ошибкой.

Какой из этих методов лучше работает для вас будет зависеть от нескольких факторов, таких как:

  • Количество перехватчиков
  • Сложность фильтрации маршрутов (ваш пример может быть упрощенным один)
  • правдоподобия, что правила фильтрации будут меняться независимо от перехватчика логики

записку о синглтоны

Имейте в виду, что услуги являются одноточечными. Они создаются один раз и повторно используются. Per Angular doco:

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

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

1 - Single перехватчик

гвоздика ответить уже привел пример для этого, как и Shashank годов. Что-то вроде этого:

function SingleInterceptor() { 
    var service = { 
     request: request 
    }; 

    return service; 

    function request(config) { 
     if (config.url === base_url + '/step-1') { 
      step1Logic(); 
     } 
     if (config.url === base_url + '/step-2') { 
      step2Logic(); 
     } 
     // etc... 
     return config; 
    } 
} 

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

2 - Множественные перехватчики (с их собственной фильтрации)

Каждый перехватчик имеет свою собственную логику для определения, применяется ли маршрут. Как:

function InterceptorStep1() { 
    var service = { 
     request: request 
    }; 

    return service; 

    function request(config) { 
     if (config.url === base_url + '/step-1') { 
      // Step 1 logic here 
     } 
     return config; 
    } 
} 

function InterceptorStep1() { 
    var service = { 
     request: request 
    }; 

    return service; 

    function request(config) { 
     if (config.url === base_url + '/step-2') { 
      // Step 2 logic here 
     } 
     return config; 
    } 
} 

Это было бы более ремонтопригодно в больших объемах, но становится неловко, если вы хотите, чтобы начать изменять правила фильтрации, или перехватчики не имеет очевидное отображение один к одному с URL. Hypothesising здесь, может быть, они не все так очевидно, как «Шаг 1», «Шаг 2» и т.д.

3 - Несколько перехватчиков (фильтрация на основе конфигурации)

Похожих на # 2, но отделить маршрут фильтрации логики от самих перехватчиков, используя провайдера для каждого.

function InterceptorB(filterUrl) { 
    var service = { 
     request: request 
    }; 

    return service; 

    function request(config) { 
     if (!filterUrl || filterUrl(config.url)) { 
      // Logic here 
     } 
     return config; 
    } 
} 

angular 
    .module('app') 
    .provider('InterceptorB', function InterceptorBProvider() { 
     var filterUrlInner; 

     this.setFilterUrlCallback = function (fn) { 
      filterUrlInner = fn; 
     }; 

     this.$get = [function InterceptorBFactory($log) { 
      return new InterceptorB(filterUrlInner); 
     }]; 
    }); 

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

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