Angular8 RXJS CanDeactivate дождаться результата наблюдаемого перед деактивацией
Я пытаюсь использовать защиту CanDeactivate, чтобы определить, когда пользователь уходит от компонента. Цель состоит в том, чтобы #1 проверить, владеет ли текущий пользователь блокировкой "Редактируется" для записи, и #2, если да, вызвать наблюдаемый объект для обновления базы данных.
Код, который у меня есть, частично работает, но есть состояние гонки, при котором блокировка не всегда снимается, вероятно, потому, что подписка на this.updateIsBeingEdited$(false)
не всегда завершается к моменту вызова следующего оператора возврата. Так что я знаю, что это неправильно реализовано.
Как сделать так, чтобы this.updateIsBeingEdited$
наблюдаемый завершается до того, как canDeactivate вернет значение?
Возвращаемое значение всегда должно быть истиной, потому что компонент всегда должен отключаться, ему просто нужно убедиться, что this.updateIsBeingEdited$.subscribe()
выполняется до завершения деактивации.
СОСТАВНАЯ ЧАСТЬ
canDeactivate(): Observable<boolean> | boolean {
// Check if Is Being Edited must be removed
if (this.mustReleaseIsBeingEdited()) {
this.removeIsBeingEditedSub = this.updateIsBeingEdited$(false).subscribe(result => {
// QUESTION: How to wait until this is complete before allowing component to deactivate?
return true;
}, err => { console.error(err); }, () => { });
// Always allow deactivation
return true;
} else {
return true;
}
}
private updateIsBeingEdited$(isBeingEdited): Observable<boolean> {
const editedObj = {
_id: this.record._id,
IsBeingEdited: isBeingEdited,
EditedBy: this.accessLevelService.getUserId()
}
return this.httpService!.postData$(
`records/_id/${editedObj._id}/IsBeingEdited/`,
editedObj
);
}
Охранник
export interface ComponentCanDeactivate {
canDeactivate: () => boolean | Observable<boolean>;
}
/**
* Guard to notify client that user has navigated away from route
* Implemented in component for managing record locks only
*/
@Injectable({
providedIn: 'root'
})
export class RecordLocksGuard implements CanDeactivate<ComponentCanDeactivate> {
canDeactivate(component: ComponentCanDeactivate): boolean | Observable<boolean> {
if (!component) {
return true;
}
component.canDeactivate();
// Always allow component to deactivate
return true;
}
}
1 ответ
Спасибо, вот обновленный код, который, похоже, работает.
СОСТАВНАЯ ЧАСТЬ
canDeactivate(): Observable<boolean> | boolean {
// Check if Is Being Edited must be removed
if (this.mustReleaseIsBeingEdited()) {
return this.updateIsBeingEdited$(false);
} else {
return of(true);
}
}
private updateIsBeingEdited$(isBeingEdited): Observable<boolean> {
const editedObj = {
_id: this.record._id,
IsBeingEdited: isBeingEdited,
EditedBy: this.accessLevelService.getUserId()
}
return this.httpService!.postData$(
`records/_id/${editedObj._id}/IsBeingEdited/`,
editedObj
);
}
Охранник
export interface ComponentCanDeactivate {
canDeactivate: () => boolean | Observable<boolean>;
}
/**
* Guard to notify client that user has navigated away from route
* Implemented in component for managing record locks only
*/
@Injectable({
providedIn: 'root'
})
export class RecordLocksGuard implements CanDeactivate<ComponentCanDeactivate> {
canDeactivate(component: ComponentCanDeactivate): boolean | Observable<boolean> {
if (!component) {
return of(true);
}
return component.canDeactivate();
}
}