5

Я использую угловой перехватчик $ http, чтобы проверить, возвращает ли запрос ajax 401 (не аутентифицирован). Если ответ равен 401, исходный запрос ставится в очередь, отображается форма входа в систему и после успешного входа в систему выполняется повторная попытка запросов в очереди. Это уже работает с $ HTTP, и источник для углового перехватчика:

define('common.service.security.interceptor', ['angular'], function() { 
'use strict'; 

angular.module('common.service.security.interceptor', ['common.service.security.retryQueue']) 

.factory('securityInterceptor', [ 
    '$injector', 
    '$location', 
    'securityRetryQueue', 
    function($injector, $location, securityRetryQueue) { 

     return function(promise) { 

      var $http = $injector.get('$http'); 


      // catch the erroneous requests 
      return promise.then(null, function(originalResponse){ 
       if(originalResponse.status === 401){ 
        promise = securityRetryQueue.pushRetryFn('Unauthorized', function retryRequest(){ 
         return $injector.get('$http')(originalResponse.config); 
        }); 
       } 

       return promise; 
      }); 
     }; 
    } 
]) 

// register the interceptor to the angular http service. method) 
.config(['$httpProvider', function($httpProvider) { 
    $httpProvider.responseInterceptors.push('securityInterceptor'); 

}]);}); 

Как я могу сделать запрос, используя этот ветер углового $ HTTP-перехватчик?

Breeze представляет собой обертку для углового сервиса $ http в файле «Бриз/Адаптеры/breeze.ajax.angular.js». Таким образом, первая идея состояла в том, чтобы сказать бризом, чтобы использовать его:

breeze.config.initializeAdapterInstance("ajax", "angular", true); 

Отладка angular.js, это показывает, что ветер в настоящее время на самом деле использует $ HTTP, но он не выполняет выше зарегистрированного перехватчик. Внутри $ http имеется массив «reverseedInterceptors», в котором хранятся зарегистрированные перехватчики. Я регистрирую этот массив для консоли. Если я использую $ http, длина этого массива равна единице (как и ожидалось), но при выполнении запроса с ветром этот массив пуст.

Вопрос в том, как я могу использовать этот перехватчик $ http с просьбами о бризе?

Вот код для breeze.ajax.angular.js, если ветерок

define('breeze.ajax.angular.module', ['breeze', 'angular'], function (breeze) { 
'use strict'; 
/* jshint ignore:start */ 
var core = breeze.core; 

var httpService; 
var rootScope; 

var ctor = function() { 
    this.name = "angular"; 
    this.defaultSettings = {}; 
}; 

ctor.prototype.initialize = function() { 

    var ng = core.requireLib("angular"); 

    if (ng) { 
     var $injector = ng.injector(['ng']); 
     $injector.invoke(['$http', '$rootScope', 
      function (xHttp, xRootScope) { 
       httpService = xHttp; 
       rootScope = xRootScope; 
     }]); 
    } 

}; 

ctor.prototype.setHttp = function (http) { 
    httpService = http; 
    rootScope = null; // to suppress rootScope.digest 
}; 

ctor.prototype.ajax = function (config) { 
    if (!httpService) { 
     throw new Error("Unable to locate angular for ajax adapter"); 
    } 
    var ngConfig = { 
     method: config.type, 
     url: config.url, 
     dataType: config.dataType, 
     contentType: config.contentType, 
     crossDomain: config.crossDomain 
    } 

    if (config.params) { 
     // Hack: because of the way that Angular handles writing parameters out to the url. 
     // so this approach takes over the url param writing completely. 
     // See: http://victorblog.com/2012/12/20/make-angularjs-http-service-behave-like-jquery-ajax/ 
     var delim = (ngConfig.url.indexOf("?") >= 0) ? "&" : "?"; 
     ngConfig.url = ngConfig.url + delim + encodeParams(config.params); 
    } 

    if (config.data) { 
     ngConfig.data = config.data; 
    } 

    if (!core.isEmpty(this.defaultSettings)) { 
     var compositeConfig = core.extend({}, this.defaultSettings); 
     ngConfig = core.extend(compositeConfig, ngConfig); 
    } 

    httpService(ngConfig).success(function (data, status, headers, xconfig) { 
     // HACK: because $http returns a server side null as a string containing "null" - this is WRONG. 
     if (data === "null") data = null; 
     var httpResponse = { 
      data: data, 
      status: status, 
      getHeaders: headers, 
      config: config 
     }; 
     config.success(httpResponse); 
    }).error(function (data, status, headers, xconfig) { 
     var httpResponse = { 
      data: data, 
      status: status, 
      getHeaders: headers, 
      config: config 
     }; 
     config.error(httpResponse); 
    }); 
    rootScope && rootScope.$digest(); 
}; 

function encodeParams(obj) { 
    var query = ''; 
    var key, subValue, innerObj; 

    for (var name in obj) { 
     var value = obj[name]; 

     if (value instanceof Array) { 
      for (var i = 0; i < value.length; ++i) { 
       subValue = value[i]; 
       fullSubName = name + '[' + i + ']'; 
       innerObj = {}; 
       innerObj[fullSubName] = subValue; 
       query += encodeParams(innerObj) + '&'; 
      } 
     } else if (value instanceof Object) { 
      for (var subName in value) { 
       subValue = value[subName]; 
       fullSubName = name + '[' + subName + ']'; 
       innerObj = {}; 
       innerObj[fullSubName] = subValue; 
       query += encodeParams(innerObj) + '&'; 
      } 
     } else if (value !== undefined) { 
      query += encodeURIComponent(name) + '=' + encodeURIComponent(value) + '&'; 
     } 
    } 

    return query.length ? query.substr(0, query.length - 1) : query; 
} 


breeze.config.registerAdapter("ajax", ctor); 

breeze.config.initializeAdapterInstance("ajax", "angular", true); 
/* jshint ignore:end */ 
}); 

ответ

6

используя метод setHttp работает для меня, чтобы использовать HTTP-перехватчики с ветерком угловым адаптером АЯКС. в моем окружении, это выглядит следующим образом:

(function() { 
    'use strict'; 

    var serviceId = 'entityManagerFactory'; 
    angular.module('app').factory(serviceId, ['$http', emFactory]); 

    function emFactory($http) { 

     var instance = breeze.config.initializeAdapterInstance("ajax", "angular"); 
     instance.setHttp($http); 

     ... 

    } 
})(); 

единственное место, где я действительно нашел любую информацию об этом в примечаниях к версии 1.4.4 на download странице. Я действительно не понимаю, что это делает. я уверен, что у одного из ветерок будет лучшее объяснение.

+0

BINGO! @almaplayer. 'setHttp' FTW. См. Мой ответ ниже. – Ward

4

Вы должны позвонить setHttp($http), как объяснено @almaplayera. Пожалуйста, отметьте его как правильный ответ.

Вот почему это необходимо.

По умолчанию, угловой адаптер ajax для ветерок инициализируется тем, что доступен любой экземпляр $ http. К сожалению, в то время, когда загружается большинство скриптов, экземпляр $http для ВАШЕГО APP не был создан. Это произойдет не до тех пор, пока ваш модуль не загрузится ... что обычно происходит долго после нагрузок бриза.

Поэтому вместо создания адаптера, который не будет работать вообще, ветер разворачивает свой собственный экземпляр $http и прокладывает угловой адаптер ajax к этому экземпляру.

Если ваш код не делает ничего особенного, это работает нормально. Это не оптимально; вы получите один дополнительный цикл $digest, чем необходимо. Но это работает для большинства людей, и давайте признаем, что более чем достаточно шума конфигурации, чтобы справиться с этим.

Но вы делаете что-то особенное. Вы настраиваете очень конкретный экземпляр $http, а не тот, который создавал для себя ветерок.

Значит, вам нужно рассказать ветер, чтобы использовать ВАШ пример $http ...и это то, что происходит, когда вы вызываете setHttp($http);

Благодаря этой обратной связи, я обновил breeze documentation on ajax adapters, чтобы описать, как настроить приложение с угловым выражением.

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