rxjs Observable 与预解析数据混合
rxjs Observable mixed with pre-resolved data
我有两个可观察的数据流。一取账号,一取权限。
我需要做的是检查当前用户是否具有管理员角色,或者具有外部角色并且当前帐户没有设置标志。但是我不知道如何使用 rxjs 做到这一点。
这是一个精简的测试用例,用于展示我正在尝试做的事情,但是因为运行时所有数据都不存在(帐户为空,或者权限尚未加载) yet), 它出错了。
我怎样才能使这个工作?
我正在使用 rxjs6。
export class ViewComponent implements OnInit {
private account: AdminUser;
private permissions: Permissions;
constructor(private _service: AdminUserService,
private _permissions: PermissionsService,
private _activatedRoute: ActivatedRoute) {
}
canEdit(): boolean {
let isAdmin = this.permissions.hasRole('Admin');
return isAdmin || (this._permissions.hasRole('External') && !this.account.isActiveDirectory);
}
ngOnInit() {
this._permissions
.getPermissions()
.subscribe(p => this.permissions = p);
this._activatedRoute.params.subscribe(
params => {
this._service.get(params.id)
.pipe(map(account => this.account = account))
.subscribe();
});
}
}
我只是猜测你的目标可能是什么。但是检查你的代码我认为你正在寻找这样的解决方案。
export class ViewComponent implements OnInit, OnDestroy {
// provide this information as boolean
canEdit = false;
private account: AdminUser;
private permissions: Permissions;
// allways collect at start and remove all subscriptions when leaving the component
private subscription: Subscription = new Subscription();
constructor(private _service: AdminUserService,
private _permissions: PermissionsService,
private _activatedRoute: ActivatedRoute) { }
ngOnInit(): void {
this.subscription.add(
this._permissions
.getPermissions()
.subscribe(permissions => {
this.permissions = permissions;
this.checkPermissions();
})
);
this.subscription.add(
this._activatedRoute.params.subscribe(
params => {
this._service.get(params.id).subscribe(account =>
this.account = account);
this.checkPermissions();
})
);
}
ngOnDestroy(): void {
// unsubscribe all subscriptions
this.subscription.unsubscribe();
}
checkPermissions(): void {
if (this.permissions && this.account) {
this.canEdit = this.permissions.hasRole('Admin') ||
(this._permissions.hasRole('External') && !this.account.isActiveDirectory);
}
}
在您的 HTML 中,我猜您想要(取消)激活一个按钮左右。那就这样吧
<button [disabled]="!canEdit">Edit something</button>
您可以将数据保留为可观察对象,而无需订阅您的组件。 Rxjs 有许多操作符和静态函数来塑造、过滤和转换它们以满足您的需要。
而不是将account
定义为AdminUser
,将permissions
定义为Permissions
;让我们将它们定义为 Observable<AdminUser>
和 Observable<Permissions>
.
然后我们可以使用 combineLatest
创建一个发出 canEdit
值的单个 observable。
export class ViewComponent {
private id$ = this._activatedRoute.params.pipe(map(params => params.id));
private account$ = this.id$.pipe(switchMap(id => this._service.get(id)));
private permissions$ = this._permissions.getPermissions();
public canEdit$ = combineLatest([this.account$, this.permissions$]).pipe(
map(([account, permissions]) =>
permissions.hasRole("Admin") ||
(permissions.hasRole("External") && !account.isActiveDirectory)
)
);
constructor(
private _service: AdminUserService,
private _permissions: PermissionsService,
private _activatedRoute: ActivatedRoute
) { }
}
如果您不熟悉 switchMap
,它基本上会为您订阅一个“内部可观察对象”并发出结果。在这种情况下,获取 id
并调用 service.get(id)
.
您似乎还想在模板中使用帐户信息以及 canEdit
值。我们可以发出一个对象,其中包含我们视图所需的所有数据(视图模型):
,而不是发出单个 boolean
export class ViewComponent {
private id$ = this._activatedRoute.params.pipe(map(params => params.id));
private account$ = this.id$.pipe(switchMap(id => this._service.get(id)));
private permissions$ = this._permissions.getPermissions();
public vm$ = combineLatest([this.account$, this.permissions$]).pipe(
map(([account, permissions]) => {
const canEdit = permissions.hasRole("Admin") || (permissions.hasRole("External") && !account.isActiveDirectory)
return { account, canEdit };
})
);
constructor(
private _service: AdminUserService,
private _permissions: PermissionsService,
private _activatedRoute: ActivatedRoute
) { }
}
您现在可以在模板中使用单个 async
管道来为您处理订阅:
<ng-container *ngIf="vm$ | async as vm">
<h1>{{ vm.account.name }}</h1>
...
<button *ngIf="vm.canEdit">Edit</button>
</ng-container>
我有两个可观察的数据流。一取账号,一取权限。
我需要做的是检查当前用户是否具有管理员角色,或者具有外部角色并且当前帐户没有设置标志。但是我不知道如何使用 rxjs 做到这一点。
这是一个精简的测试用例,用于展示我正在尝试做的事情,但是因为运行时所有数据都不存在(帐户为空,或者权限尚未加载) yet), 它出错了。
我怎样才能使这个工作?
我正在使用 rxjs6。
export class ViewComponent implements OnInit {
private account: AdminUser;
private permissions: Permissions;
constructor(private _service: AdminUserService,
private _permissions: PermissionsService,
private _activatedRoute: ActivatedRoute) {
}
canEdit(): boolean {
let isAdmin = this.permissions.hasRole('Admin');
return isAdmin || (this._permissions.hasRole('External') && !this.account.isActiveDirectory);
}
ngOnInit() {
this._permissions
.getPermissions()
.subscribe(p => this.permissions = p);
this._activatedRoute.params.subscribe(
params => {
this._service.get(params.id)
.pipe(map(account => this.account = account))
.subscribe();
});
}
}
我只是猜测你的目标可能是什么。但是检查你的代码我认为你正在寻找这样的解决方案。
export class ViewComponent implements OnInit, OnDestroy {
// provide this information as boolean
canEdit = false;
private account: AdminUser;
private permissions: Permissions;
// allways collect at start and remove all subscriptions when leaving the component
private subscription: Subscription = new Subscription();
constructor(private _service: AdminUserService,
private _permissions: PermissionsService,
private _activatedRoute: ActivatedRoute) { }
ngOnInit(): void {
this.subscription.add(
this._permissions
.getPermissions()
.subscribe(permissions => {
this.permissions = permissions;
this.checkPermissions();
})
);
this.subscription.add(
this._activatedRoute.params.subscribe(
params => {
this._service.get(params.id).subscribe(account =>
this.account = account);
this.checkPermissions();
})
);
}
ngOnDestroy(): void {
// unsubscribe all subscriptions
this.subscription.unsubscribe();
}
checkPermissions(): void {
if (this.permissions && this.account) {
this.canEdit = this.permissions.hasRole('Admin') ||
(this._permissions.hasRole('External') && !this.account.isActiveDirectory);
}
}
在您的 HTML 中,我猜您想要(取消)激活一个按钮左右。那就这样吧
<button [disabled]="!canEdit">Edit something</button>
您可以将数据保留为可观察对象,而无需订阅您的组件。 Rxjs 有许多操作符和静态函数来塑造、过滤和转换它们以满足您的需要。
而不是将account
定义为AdminUser
,将permissions
定义为Permissions
;让我们将它们定义为 Observable<AdminUser>
和 Observable<Permissions>
.
然后我们可以使用 combineLatest
创建一个发出 canEdit
值的单个 observable。
export class ViewComponent {
private id$ = this._activatedRoute.params.pipe(map(params => params.id));
private account$ = this.id$.pipe(switchMap(id => this._service.get(id)));
private permissions$ = this._permissions.getPermissions();
public canEdit$ = combineLatest([this.account$, this.permissions$]).pipe(
map(([account, permissions]) =>
permissions.hasRole("Admin") ||
(permissions.hasRole("External") && !account.isActiveDirectory)
)
);
constructor(
private _service: AdminUserService,
private _permissions: PermissionsService,
private _activatedRoute: ActivatedRoute
) { }
}
如果您不熟悉 switchMap
,它基本上会为您订阅一个“内部可观察对象”并发出结果。在这种情况下,获取 id
并调用 service.get(id)
.
您似乎还想在模板中使用帐户信息以及 canEdit
值。我们可以发出一个对象,其中包含我们视图所需的所有数据(视图模型):
boolean
export class ViewComponent {
private id$ = this._activatedRoute.params.pipe(map(params => params.id));
private account$ = this.id$.pipe(switchMap(id => this._service.get(id)));
private permissions$ = this._permissions.getPermissions();
public vm$ = combineLatest([this.account$, this.permissions$]).pipe(
map(([account, permissions]) => {
const canEdit = permissions.hasRole("Admin") || (permissions.hasRole("External") && !account.isActiveDirectory)
return { account, canEdit };
})
);
constructor(
private _service: AdminUserService,
private _permissions: PermissionsService,
private _activatedRoute: ActivatedRoute
) { }
}
您现在可以在模板中使用单个 async
管道来为您处理订阅:
<ng-container *ngIf="vm$ | async as vm">
<h1>{{ vm.account.name }}</h1>
...
<button *ngIf="vm.canEdit">Edit</button>
</ng-container>