Angular6 routing guard CanDeactivate, listens when the browser backs up and jumps to another route when the condition is met

when I use the CanDeactivate route guard to handle the operation when leaving from the current route, I will determine whether the data of the current route page is saved, if not, I will pop up a prompt, and then when the user clicks Yes, CanDeactivate returns true, to return to the previous route, but what I expect at this time is that when I click Yes, I jump to another route, and then there will be the problem of repeated loop judgment. What should I do with

The

clipboard.png
code is as follows:
routing code

export interface AbstractCanDeactivate {
  canDeactivate();
}


@Injectable({
  providedIn: "root"
})
export class CanDeactivateGuard implements CanDeactivate<AbstractCanDeactivate> {
  constructor(
    private router: Router
  ) {

  }
  canDeactivate(
    component: AbstractCanDeactivate,
    route: ActivatedRouteSnapshot,
    state: RouterStateSnapshot,
    nextState: RouterStateSnapshot
  ): Observable<boolean> | boolean {

    return component.canDeactivate();
  }
}

pop-up prompt code:

  /**
   * 
   */
  canDeactivate() {
    return Observable.create((observer) => {
      if (!this.isSave) {
        this.modalService.confirm({
          nzTitle: "",
          nzContent: "",
          nzOnOk: async () => {
            this.routeNavigate.navigate(["/setting/index/myOrder"]);
            observer.next(true);
          },
          nzOnCancel: () => {
            observer.next(false);
          }
        });
      } else {
        observer.next(true);
      }
    });
  }

Register the routing table of the sub-module, and register directly to the interface that forbids fallback:


{ path: "confirm", component: ConfirmOrderComponent , canDeactivate: [CanDeactivateGuard] },

this guard is only a hook function, and the final return value represents the status of the current jump behavior. In the middle, you can initiate other jumps using the router service. This example can be found in the ide/router-sharpteach-authguard-to-authenticate" rel=" nofollow noreferrer "> document on the official website, but the hook in the example is canActive, and here is canDeactive.

Note: calls the router service in hook to redirect, which will directly interrupt the parsing process of the current route. The return value here is just to make the logic in guard clearer. For more information, please see the official document:

This secondary navigation automatically cancels the current navigation; checkLogin () returns false just to be clear about that.
< hr >

updated
Sorry for the late reply. I was halfway through the answer yesterday, and then something happened all of a sudden. Combined with your updated feedback and some code written by my previous project, there are still some slight differences between canActivate and canDeactivate, that is, if it is the former, there will be no problem with the direct jump, because the current guard will only be triggered once, while the latter is problematic, because every time you want to jump from the current route, you will call the logic inside canDeactive, which forms the infinite loop mentioned in your problem description.

on this point, I thought about it carefully last night. The reason why the code in my project can run is that the target url to be redirected before is predetermined to die. When the jump target route is this url, the direct return true, should have called the canDeactivate internal logic twice, but you should expect it to be called only once.

if this is the case, the logic of the jump route cannot be put inside the canDeactivate guard, but should be placed in a series of RouterEvent, such as NavigationStart. For specific code, take a look at the link . In the example, jumping to any other page from the home page will prompt you, click OK to jump, and click cancel to retain it. It should be the same logic as you here.

Last but not least, this question has also been mentioned in github's issue, and the questioner also hopes that if the new route jump logic is skipped in guard, the current guard should not be triggered again. The author of angular-router believes that as far as guard is concerned, he hopes that there will not be too many side effects (that is, the new route here). Because the better timing for these side effects is in a series of RouterEvent triggered by router, guard should be as "pure" as possible to comply with the principle of single responsibility.

Menu