简体   繁体   中英

Prevent Angular component rendering after router.navigate

If to execute this.router.navigate(['someRoute']) inside ngOnInit , initial component still being rendered before redirection.

For example I have some component:

@Component({
  selector: 'my-app',
  template: '<child-comp></child-comp>',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent  {
  constructor(private router: Router) {
  }

  ngOnInit() {
    console.log('ngOnInit from AppComponent');
    this.router.navigate(['another']);
  }
}

It contains child in template:

@Component({
  selector: 'child-comp',
  template: '<div>CHILD<div>'
})
export class ChildComponent  {
  ngOnInit() {
    console.log('Should NOT be called (ChildComponent)');
  }
}

And before view initialization (inside ngOnInit hook) I perform redirection to another component:

@Component({
  selector: 'another-comp',
  template: '<div>Another<div>'
})
export class AnotherComponent  {
  ngOnInit() {
    console.log('Should be called (AppComponent)');
  }
}

I expect that child component will not be initialized, as it happens after redirection call, but it's ngOnInit() hook is still gets triggered.

How to prevent child component initialization in this case?

Stackblitz: https://stackblitz.com/edit/angular-gjunnr?file=src%2Fapp%2Fanother%2Fanother.component.ts

PS I didn't find the way to prevent component rendering and end up with modifying design.

This is what guards are for:

Create a guard that determines if the user is allowed to go to that page:

@Injectable({
  providedIn: 'root'
})
export class PreventNavigateGuard implements CanActivate {
  constructor(public router: Router) {}
  canActivate(
    next: ActivatedRouteSnapshot,
    state: RouterStateSnapshot
  ):
    | Observable<boolean | UrlTree>
    | Promise<boolean | UrlTree>
    | boolean
    | UrlTree {
    return this.router.createUrlTree(["another"]);
  }
}

Then in your routes use canActivate to guard it:

const appRoutes: Routes = [
  { path: '', component: AppComponent, canActivate: [PreventNavigateGuard] },
  { path: 'another', component: AnotherComponent },
];

https://angular.io/guide/router#milestone-5-route-guards

Here is a stackblitz: https://stackblitz.com/edit/angular-kbzx1v

Alternatively, you can just apply an ngIf to the child component and only have it render when a property in the app.component is true.

<child-comp *ngIf="false"></child-comp>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM