我有以下代码,我在其中根据权限生成菜单,我在咨询服务“ this.auth.permissions”,该服务应返回一个值,但无法从应用程序访问它.menu,但是如果我调用observable并为其提供一个控制台,则如果它向我显示数据,但是我不需要observable而是直接数据,可以在“ hasExpectedPermissions”函数中使用它。
app.menu.js
import { AuthService } from './@auth/auth.service';
@Injectable()
export class AppMenu implements OnInit{
permissions:any=[];
dashboardMenu: NbMenuItem[] = [];
constructor(private auth: AuthService){
this.auth.permissions$.subscribe(permi=>{
console.log("permi",permi)
})
}
ngOnInit(){
}
getMenu(): Observable<NbMenuItem[]> {
const dashboardMenu = [
{
title: 'Dashboard',
icon: 'home-outline',
link: '/',
home: true,
children: undefined,
},
{
title: 'Users',
icon: 'person-outline',
link: '/users',
data: ['create:user', 'read:user'],
children: [
{
title: 'Users',
link: '/users',
data: ['read:user'],
},
{
title: 'Create User',
link: '/edit-user',
data: ['create:user'],
},
],
},
];
function hasExpectedPermissions(page) {
let permissionsa = this.auth.permissions;
for(const data of page.data) {
console.log("data",data);
page.enabled = permissionsa.indexOf(data) > -1 || page.enabled;
}
return page.enabled;
}
function getAllowedPages(pages) {
return pages.filter(function (page) {
return (page.data === undefined) || (hasExpectedPermissions(page) === true);
}).map(page => {
if (page.children) {
page.children = getAllowedPages(page.children);
}
return page;
});
}
console.log('get', getAllowedPages(dashboardMenu) );
return of([...dashboardMenu]);
}
}
auth.service.js
public permissions: string[];
public permissions$ = new Observable((observer) => {
this.auth0Client$.subscribe(client => {
if (client.isAuthenticated()) {
from(client.getTokenSilently()).subscribe(token => {
this.tokenSilently$ = token;
const decodedToken = this.helper.decodeToken(token);
this.permissions = decodedToken.permissions;
observer.next(decodedToken.permissions);
});
}
});
}) as Observable<string[]>;
答案 0 :(得分:0)
如果您异步获取权限,则需要在服务返回权限后在subscribe
的正文中构建菜单。
首先,我重构了您的服务,以在管道中的concatMap
中进行链式可观察的调用,而不是使用内部订阅和不必要的Observable
包装器。
auth.service.ts
permissions$ = this.auth0Client$.pipe(
concatMap(client => client.isAuthenticated() ? from(client.getTokenSilently()) : of(null)),
map(token => {
if (!token) {
return [];
}
const decodedToken = this.helper.decodeToken(token);
return decodedToken.permissions;
})
);
然后在组件中,您在ngOnInit
中(而不是在构造函数中)进行订阅,并在subscribe
中构建菜单。我没有包括菜单本身的构建,因为此答案更多地是关于向您显示可观察对象的设置。
app-menu.component.ts
export class AppMenu implements OnInit{
constructor(private auth: AuthService) {}
permissions = [];
ngOnInit(): void {
this.auth.permissions$.subscribe(permissions => {
this.permissions = permissions;
this.buildMenu();
});
}
private buildMenu(): void {
// TODO: implement
}
}
我不确定auth0client
是什么,但是如果它做的事情比单个http请求更复杂,则需要研究取消订阅的情况。