gpt4 book ai didi

Angular 2 ngIf 可观察?

转载 作者:太空狗 更新时间:2023-10-29 17:31:41 25 4
gpt4 key购买 nike

我有一个非常简单的服务,它的工作是从 api/authenticate url 获取 200 或 401。

auth.service.ts

@Injectable()
export class AuthService {

constructor(private http: Http) {

}

authenticateUser(): Observable<any> {
return this.http.get(AppSettings.authenitcationEnpoint)
.map(this.extractData)
.catch(this.handleError);
}

private extractData(response: Response) {
let body = response;
return body || {};
}

private handleError(error: Response) {
let errMsg: string;
if (error instanceof Response) {
errMsg = `${error.status} - ${error.statusText || ''}`;
} else {
errMsg = error.toString();
}
return Observable.throw(errMsg);
}
}

现在我想在我的 html 中使用它,我知道我可以创建一个订阅者并根据响应或错误代码设置一个变量,但我的问题是我将不得不在所有地方复制代码。我要的很简单

<div *ngIf="authService.AuthenticateUser()">my content</div>

如果它的 401 来自 handleError 则隐藏,否则显示 div。

这就像从 Observable 获取 bool 值。我也有 AuthGuard。

authguard.ts

@Injectable()
export class AuthGuard implements CanActivate {

private isActive: boolean = true;
constructor(private authService: AuthService, private router: Router) {
}

canActivate(): boolean {
this.authService.authenticateUser()
.subscribe(() => {},
error => {
if (error.indexOf("401") >= 0) {
let link = ['contactus'];
this.router.navigate(link);
this.isActive = false;
}
});
return this.isActive;
}

}

我也不能在 ngIf 中使用 authGuard.canActive()。有没有更简单的方法可以在不重复代码的情况下做到这一点。我很确定 AuthGuard 无法正常工作,因为它必须每次都返回 true,因为订阅需要时间。

app.component.ts

export class AppComponent {
private isAuthenticated: boolean = false;

constructor(private authService: AuthService,private authGuard: AuthGuard) {
this.authService.authenticateUser()
.subscribe(response => {
if (response.status == 200)
this.isAuthenticated = true;
},
error => {
if (error.indexOf("401") >= 0)
this.isAuthenticated = false;
});
}
}

home.component.ts

export class HomeComponent implements OnInit {

constructor(private http: Http, private authService: AuthService, private utilityService: UtilityService, private homeService: HomeService, private factoryService: FactoryService, private supplierService: SupplierService, private businessAreaService: BusinessAreaService, private router: Router) {
this.authService.authenticateUser()
.subscribe(response => {
if (response.status == 200)
this.isAuthenticated = true;
},
error => {
if (error.indexOf("401") >= 0)
this.isAuthenticated = false;
});
this.customData = new CustomData(http);
}
}

如您所见,有很多重复的代码。我正在努力避免重复。

当我调用我的 api 时,会出现一个弹出窗口,要求输入用于 Windows 身份验证的 Windows 用户名/密码。在取消该弹出窗口之前,我不会收到 401。所以我想隐藏我的菜单+主页组件。

在我的服务中,我在 ma​​p 中得到 response:200和未授权:catch block 中的 401

最佳答案

在这里,您返回的是一个可观察对象而不是值:

authenticateUser(): Observable<any> {
return this.http.get(AppSettings.authenitcationEnpoint)
.map(this.extractData)
.catch(this.handleError);
}

您应该做的是在您的服务中创建一个属性,然后在您的 html 中使用该属性,而不是订阅可观察对象的函数。像这样的东西:

@Injectable()
export class AuthService {

isAuthenticated: boolean = false; //The variable

constructor(private http: Http) {
}

authenticateUser(): Observable<any> {
return this.http.get(AppSettings.authenitcationEnpoint)
.map(this.extractData)
.catch(this.handleError);
}

private extractData(response: Response) {
let body = response;
this.isAuthenticated = body.isAuthenticated; //here you assign a value to variable
return body || {};
}

private handleError(error: Response) {
let errMsg: string;
if (error instanceof Response) {
errMsg = `${error.status} - ${error.statusText || ''}`;
} else {
errMsg = error.toString();
}
return Observable.throw(errMsg);
}
}

然后,在您的 html 中,只需使用:

<div *ngIf="authService.isAuthenticated">my content</div>

另一种方法是使用 async 管道。因此, View 将等待观察返回,然后再制作摘要循环。像这样的东西:

<div *ngIf="authService.AuthenticateUser() | async">my content</div> // Here you use the async pipe

关于 Angular 2 ngIf 可观察?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40977839/

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