Angularjs 在angular+;中以类型安全的方式使用带有自定义字段的$http侦听器;打字稿
我目前实现了一个angularAngularjs 在angular+;中以类型安全的方式使用带有自定义字段的$http侦听器;打字稿,angularjs,typescript,Angularjs,Typescript,我目前实现了一个angular$http拦截器,根据本地存储值向请求添加自定义头(我需要在我的应用程序中实现一个“Su”功能) 我需要在一些特殊请求上“停用”此行为(=我需要能够在每个请求的基础上配置此行为),并且我希望在调用我的$http方法时放置一个额外的配置参数来表示这一点 拦截器的外观如下所示: $httpProvider.interceptors.push((localStorageService: ng.local.storage.ILocalStorageService) =>
$http
拦截器,根据本地存储值向请求添加自定义头(我需要在我的应用程序中实现一个“Su”功能)
我需要在一些特殊请求上“停用”此行为(=我需要能够在每个请求的基础上配置此行为),并且我希望在调用我的$http
方法时放置一个额外的配置参数来表示这一点
拦截器的外观如下所示:
$httpProvider.interceptors.push((localStorageService: ng.local.storage.ILocalStorageService) => {
return {
request: (config: ng.IRequestShortcutConfig) => {
var su = localStorageService.get<string>('Su');
if(su && !("avoidSudo" in config)){
config.headers.Su = `{ "principal": "${su}" }`;
}
return config;
}
}
});
module mymodule {
export class SkipSudoRequestShortcutConfig implements ng.IRequestShortcutConfig {
// For testing purposes only
_noSudo: boolean;
constructor(
public params?: any,
public headers?: any,
public xsrfHeaderName?: string,
public xsrfCookieName?: string,
public cache?: any,
public withCredentials?: boolean,
public data?: any,
public transformRequest?: any,
public transformResponse?: any,
public timeout?: any,
public responseType?: string
){
this._noSudo = true;
}
}
}
var config = new SkipSudoRequestShortcutConfig();
console.log(config instanceof SkipSudoRequestShortcutConfig); // Shows true
console.log(config._noSudo); // Shows true
this.$http.get('/api/sessions/current', config)
在typescript 1.6中,此代码不会编译为$http.get()
,第二个参数应该是ng.IRequestShortcutConfig
,它显然不包含我的特定avoidSudo
字段(typescript编译错误就在这里)
我可以通过将{avoidSudo:true}
替换为{avoidSudo:true}
来解决编译错误,但就类型安全而言,这显然并不理想
为此,我尝试创建一个新的skipusudorequestshortcutconfig
专用类(实现ng.IRequestShortcutConfig
)。大概是这样的:
$httpProvider.interceptors.push((localStorageService: ng.local.storage.ILocalStorageService) => {
return {
request: (config: ng.IRequestShortcutConfig) => {
var su = localStorageService.get<string>('Su');
if(su && !("avoidSudo" in config)){
config.headers.Su = `{ "principal": "${su}" }`;
}
return config;
}
}
});
module mymodule {
export class SkipSudoRequestShortcutConfig implements ng.IRequestShortcutConfig {
// For testing purposes only
_noSudo: boolean;
constructor(
public params?: any,
public headers?: any,
public xsrfHeaderName?: string,
public xsrfCookieName?: string,
public cache?: any,
public withCredentials?: boolean,
public data?: any,
public transformRequest?: any,
public transformResponse?: any,
public timeout?: any,
public responseType?: string
){
this._noSudo = true;
}
}
}
var config = new SkipSudoRequestShortcutConfig();
console.log(config instanceof SkipSudoRequestShortcutConfig); // Shows true
console.log(config._noSudo); // Shows true
this.$http.get('/api/sessions/current', config)
这样称呼:
$httpProvider.interceptors.push((localStorageService: ng.local.storage.ILocalStorageService) => {
return {
request: (config: ng.IRequestShortcutConfig) => {
var su = localStorageService.get<string>('Su');
if(su && !("avoidSudo" in config)){
config.headers.Su = `{ "principal": "${su}" }`;
}
return config;
}
}
});
module mymodule {
export class SkipSudoRequestShortcutConfig implements ng.IRequestShortcutConfig {
// For testing purposes only
_noSudo: boolean;
constructor(
public params?: any,
public headers?: any,
public xsrfHeaderName?: string,
public xsrfCookieName?: string,
public cache?: any,
public withCredentials?: boolean,
public data?: any,
public transformRequest?: any,
public transformResponse?: any,
public timeout?: any,
public responseType?: string
){
this._noSudo = true;
}
}
}
var config = new SkipSudoRequestShortcutConfig();
console.log(config instanceof SkipSudoRequestShortcutConfig); // Shows true
console.log(config._noSudo); // Shows true
this.$http.get('/api/sessions/current', config)
在拦截器中的用法如下:
request: (config: ng.IRequestShortcutConfig) => {
var su = localStorageService.get<string>('Su');
console.log(config instanceof SkipSudoRequestShortcutConfig); // Shows *false* :(
// console.log(config._noSudo); // Doesn't compile, but if executed at runtime with a breakpoint, it works and display true
if(su && !(config instanceof mymodule.SkipSudoRequestShortcutConfig)){
config.headers.Su = `{ "principal": "${su}" }`;
}
return config;
}
请求:(config:ng.IRequestShortcutConfig)=>{
var su=localStorageService.get('su');
console.log(skipusudorequestshortcutconfig的配置实例);//显示*false*:(
//console.log(config._noSudo);//不编译,但如果在运行时使用断点执行,它将工作并显示true
if(su&!(mymodule.SkipSudoRequestShortcutConfig的配置实例)){
config.headers.Su=`{“principal”:“${Su}”}`;
}
返回配置;
}
但是一旦进入请求
处理程序,instanceof
测试就失败了
我想知道实现这一目标的最佳/最简单的方法是什么。
您是否认为ng.IRequestShortcutConfig
缺少一个特殊的config
字段,该字段允许将$http
调用中的自定义字段放入拦截器处理程序
提前感谢,重要的是要记住,TypeScript中的类型只是“类型助手”,在传输到javascript时会被删除。因此,您不需要实现新的$http服务。相反,您可以创建一个满足您需要的新类型 实际上,这是因为缺少角度类型定义 您可以通过创建以下接口来修复此问题
export interface IRequestShortcutConfigWithCustomConfig extends ng.IRequestShortcutConfig {
[key: string]: any;
}
我使用的是字典样式的类型,因为它支持所有内容。但是如果不需要一般定义,可以将其更改为avoidSudo:boolean;
export interface IHttpServiceWithCustomConfig extends ng.IHttpService {
get<T>(url: string, config?: IRequestShortcutConfigWithCustomConfig): ng.IHttpPromise<T>;
}
使用IHttpInterceptor
export interface IRequestConfigWithCustomConfig extends ng.IRequestConfig, IRequestShortcutConfigWithCustomConfig {
}
export interface IHttpInterceptorWithCustomConfig extends ng.IHttpInterceptor {
request?: (config: IRequestConfigWithCustomConfig) => IRequestConfigWithCustomConfig | ng.IPromise<IRequestConfigWithCustomConfig>;
}
导出接口IRequestConfigWithCustomConfig扩展了ng.IRequestConfig、IRequestShortcutConfigWithCustomConfig{
}
使用CustomConfig扩展ng.IHttpInterceptor导出接口IHttpInterceptor{
请求?:(配置:IRequestConfigWithCustomConfig)=>IRequestConfigWithCustomConfig | ng.IPromise;
}
Hi Fred。你可能比我更了解TypScript,但我也会这么做:定义一个扩展IRequestShortcutConfig的SkipsUpsRequestShortcutConfig接口/类。你能提供更多关于“类信息不是通过角度从$http.get()调用传输到拦截器处理程序”的信息(代码+错误)吗。当然!我刚刚更新了反映我在skipusudorequestshortcutconfig
上测试的描述。我将使skipusudorequestshortcutconfig成为一个扩展skipusudorequestshortcutconfig的接口,并包含一个可选的布尔字段skipusudo
。将该接口的实例传递给$http应该可以正常工作,因为它扩展了KipsudorRequestShortcutConfig。我会让拦截器的请求函数以SkipudorRequestShortcutConfig实例作为参数。我不会使用instanceof check,而是简单地测试config.skipSudo
是否真实。根本没有测试:我从未将TypScript用于Angular 1,也没有使用TS的经验。我不能将skipusudorequestshortcutconfig
实例作为请求
回调的参数,因为在大多数情况下,我会一直将标准的ng.IRequestShortcutConfig
传递给$http
调用。您是否可以不使用拦截器而直接重写/继承普通的$httpProvider
>并传递普通请求,但是否将您的SkipSudoRequestShortcutConfig
检查添加到其中?