gpt4 book ai didi

angularjs http拦截器类(ES6)失去与 'this'的绑定(bind)

转载 作者:行者123 更新时间:2023-12-03 14:34:36 25 4
gpt4 key购买 nike

我正在使用 ES6 类构建和 AngularJS 应用程序,并将 traceur 转换为 AMD 格式的 ES5。

在我的模块中,我导入拦截器类并将其注册为服务,然后使用 module.config 中的 $httpProvider.interceptors 注册此服务:

var commonModule = angular.module(moduleName, [constants.name]);

import authenticationInterceptor from './authentication/authentication.interceptor';

commonModule.service('authenticationInterceptor', authenticationInterceptor);

commonModule.config( $httpProvider => {
$httpProvider.interceptors.push('authenticationInterceptor');
});

我的拦截器类同时注入(inject) $q $窗口服务,将它们保存在构造函数中以供以后使用。我使用调试器跟踪了这一部分,并且注入(inject)正常进行:
'use strict';
/*jshint esnext: true */

var authenticationInterceptor = class AuthenticationInterceptor {

/* ngInject */
constructor($q, $window) {
this.$q = $q;
this.$window = $window;
}

responseError(rejection) {
var authToken = rejection.config.headers.Authorization;
if (rejection.status === 401 && !authToken) {
let authentication_url = rejection.data.errors[0].data.authenticationUrl;
this.$window.location.replace(authentication_url);
return this.$q.defer(rejection);
}
return this.$q.reject(rejections);
}
}

authenticationInterceptor.$inject = ['$q', '$window'];

export default authenticationInterceptor;

当我提出一个以 响应的请求时401 拦截器会适本地触发,但在“responseError”方法中,“this”变量指向窗口对象而不是我的拦截器,因此我无权访问 这个.$q 这个.$窗口 .

我不知道为什么?有任何想法吗?

最佳答案

上下文( this )丢失了,因为 Angular 框架只保留对处理函数本身的引用,并在没有任何上下文的情况下直接调用它们,如 alexpods已经指出。

我最近写了一篇关于写作的博文$http使用 TypeScript 的拦截器,这也适用于 ES6 类:AngularJS 1.x Interceptors Using TypeScript .

总结一下我在这篇文章中讨论的内容,以免丢失this在您的处理程序中,您必须将方法定义为箭头函数,从而有效地将函数直接放在类的 constructor 中。编译后的 ES5 代码中的函数。

class AuthenticationInterceptor {

/* ngInject */
constructor($q, $window) {
this.$q = $q;
this.$window = $window;
}

responseError = (rejection) => {
var authToken = rejection.config.headers.Authorization;
if (rejection.status === 401 && !authToken) {
let authentication_url = rejection.data.errors[0].data.authenticationUrl;
this.$window.location.replace(authentication_url);
return this.$q.defer(rejection);
}
return this.$q.reject(rejections);
}
}

如果你 真的坚持将你的拦截器写成一个完全基于原型(prototype)的类,你 可以为您的拦截器定义一个基类并扩展它。基类将用实例方法替换原型(prototype)拦截器函数,因此我们可以这样编写拦截器:
class HttpInterceptor {
constructor() {
['request', 'requestError', 'response', 'responseError']
.forEach((method) => {
if(this[method]) {
this[method] = this[method].bind(this);
}
});
}
}

class AuthenticationInterceptor extends HttpInterceptor {

/* ngInject */
constructor($q, $window) {
super();
this.$q = $q;
this.$window = $window;
}

responseError(rejection) {
var authToken = rejection.config.headers.Authorization;
if (rejection.status === 401 && !authToken) {
let authentication_url = rejection.data.errors[0].data.authenticationUrl;
this.$window.location.replace(authentication_url);
return this.$q.defer(rejection);
}
return this.$q.reject(rejections);
}
}

关于angularjs http拦截器类(ES6)失去与 'this'的绑定(bind),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28638600/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com