0

我正在尝试使用 CanDeactivate 防护来检测用户何时离开组件。目的是 #1 检查当前用户是否拥有记录上的“正在编辑”锁,如果是 #2,则调用 observable 来更新数据库。

我拥有的代码部分工作,但有一个竞争条件,锁并不总是被释放,可能是因为在this.updateIsBeingEdited$(false)调用下一个 return 语句时订阅并不总是完成。所以我知道这没有正确实施。

如何使this.updateIsBeingEdited$可观察对象在 canDeactivate 返回值之前完成?

返回值应始终为 true,因为组件应始终停用,它只需要确保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;
  }
}
4

1 回答 1

0

谢谢,这是似乎正在工作的更新代码。

零件

  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();
  }
}
于 2019-11-17T17:29:08.137 回答