我创建了一个结构指令来检查用户是否具有某些权限。权限是从后端获取并保存在服务本身中。结构指令按DI注入服务,并应检查服务中是否存在权限。
这个想法:服务应该从后端获取所有权限 - >通过指令检查权限 - >渲染如果真的
问题是该服务无法获取服务。服务等待所有来自结构指令的查询,然后开始获取服务。
它看起来像这样:
authority.directive.ts
@Directive({
selector: '[authority]'})
export class AuthorityDirective {
constructor(private userService: UserService,
private templateRef: TemplateRef<any>,
private viewContainer: ViewContainerRef) {
}
@Input() set bdAuthority(authName: string) {
if (this.userService.hasAuthority(authName)) {
this.viewContainer.createEmbeddedView(this.templateRef);
return;
}
this.viewContainer.clear();
return;
}
}
和 authority.service.ts 一样
// check if the current user has the defined privilege
public hasAuthority(authorityName: string): boolean {
return (
this.authorityCache
.filter((authority) => {
return authorityName === authority.name
})
.length) > 0;
}
public onBrowserReload(tempUser: User) {
this.getUserById(tempUser.id).subscribe(user => {
this.updatePrivilegesAndUser(user);
});
}
}
}
有没有提前开始服务?
答案 0 :(得分:0)
结构指令旨在根据应该预先评估的条件来更改DOM。因为在呈现视图时调用服务,此时您的服务没有返回任何内容。 根据您的要求,您应该在ngOnInit()生命挂钩中调用您的服务并将结果保存在局部变量中。 并根据您的本地变量检查条件。
答案 1 :(得分:0)
基于上次答复,我给了自己调查任务,并提出了类似问题的解决方案。
我必须从后端端点刷新一个权限数组,并在结构化指令中确定此数组,以便确定用户是否可以看到该元素,我正在使用相同的代码来解决该问题,并且出现相同的错误,对后端的权限数组调用刷新速度不够快,因此解决方案是使用和AsyncSubject。调用完成后,AsyncSubject将解析为一个值,因此您可以从方法中将其返回。
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { BehaviorSubject, AsyncSubject } from 'rxjs';
import { Observable, of } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class PermissionsService {
baseUrl = '/apiURL/v5';
permissionsSubject = new AsyncSubject;
hasPermissions = false;
constructor(private http: HttpClient) { }
async updatePermissions(clientId, roleName) {
const response = await this.http.get(this.getRoleUrl(clientId, roleName)).toPromise();
this.permissionsSubject.next(response['permissions'] || []);
this.permissionsSubject.complete(); // Once I finish sending the value that I need i end the subject to propagate its value to all the subscribers.
}
getRoleUrl(clientId, roleName) {
return `${this.baseUrl}/client/${clientId}/roles/${roleName}`;
}
setCachedPermissions(permissions) {
this.permissionsSubject.next(permissions);
}
getCachedPermissions() {
return this.permissionsSubject.asObservable();
}
// This is the method used by the structural directive to determine if the object is rendered
cacheHasPermission(slug) {
return new Promise((resolve, reject) => {
this.getCachedPermissions().subscribe((permissions: String[]) => {
resolve(permissions.includes(slug));
});
});
}
}