Router Navigate does not call ngOnInit when same page

前端 未结 12 972
时光取名叫无心
时光取名叫无心 2020-11-28 03:20

I am calling router.navigate on same page with some query string parameters. In this case, ngOnInit() does not call. Is it by default or do I need

相关标签:
12条回答
  • 2020-11-28 03:27

    I've had the same issue, additionally I got the warning:

    did you forget to call `ngZone.run()`
    

    This site provided the best solution:

    import { Router } from '@angular/router';
    import { NgZone } from '@angular/core';
    
    ...
    
      constructor(
        private ngZone:NgZone,
        private _router: Router
      ){ }
    
      redirect(to) {
        // call with ngZone, so that ngOnOnit of component is called
        this.ngZone.run(()=>this._router.navigate([to]));
      }
    
    0 讨论(0)
  • 2020-11-28 03:33

    On your navigation method,

    this.router.routeReuseStrategy.shouldReuseRoute = () => false;
    this.router.onSameUrlNavigation = 'reload';
    this.router.navigate(['/document'], {queryParams: {"search": currentSearch}});
    
    0 讨论(0)
  • 2020-11-28 03:35

    Here is a collection of the best ideas on this page with more information

    Solution 1 - Use params subscription:

    Tutorial: https://angular-2-training-book.rangle.io/routing/routeparams#reading-route-parameters

    Docs: https://angular.io/api/router/ActivatedRoute#params

    In each of your routing components that use param variables include the following:

    import { Component, OnInit, OnDestroy } from '@angular/core';
    import { ActivatedRoute } from '@angular/router';
    import { Subscription } from 'rxjs';
    
    // ...
    
    @Component({
        // ...
    })
    export class MyComponent implements OnInit, OnDestroy {
        paramsSub: Subscription;
    
        // ...
    
        constructor(activeRoute: ActivatedRoute) {
    
        }
    
        public ngOnInit(): void {
            // ...
            this.paramsSub = this.activeRoute.params.subscribe(val => {
                // Handle param values here
            });
    
            // ...
        }
    
        // ...
    
        public ngOnDestroy(): void {
            // Prevent memory leaks
            this.paramsSub.unsubscribe();
        }
    }
    

    Some common issues with this code is that subscriptions are asynchronous and can be trickier to deal with. Also you can't forget to unsubscribe on ngOnDestroy or else bad things can happen.

    Good thing is that this is the most documented and common way to handle this problem. There's also a performance improvement doing it this way since you are reusing the template instead of destroying and recreating each time you visit a page.

    Solution 2 - shouldReuseRoute / onSameUrlNavigation:

    Docs: https://angular.io/api/router/ExtraOptions#onSameUrlNavigation

    Docs: https://angular.io/api/router/RouteReuseStrategy#shouldReuseRoute

    Docs: https://angular.io/api/router/ActivatedRouteSnapshot#params

    Find where RouterModule.forRoot is located in your project (normally found in app-routing.module.ts or app.module.ts):

    const routes: Routes = [
       // ...
    ];
    
    // ...
    
    @NgModule({
        imports: [RouterModule.forRoot(routes, {
            onSameUrlNavigation: 'reload'
        })],
        exports: [RouterModule]
    })
    

    Then in AppComponent add the following:

    import { Component, OnInit} from '@angular/core';
    import { Router } from '@angular/router';
    
    // ...
    @Component({
        // ...
    })
    export class AppComponent implements OnInit {
        constructor(private router: Router) {
        }
    
        ngOnInit() {
            // Allows for ngOnInit to be called on routing to the same routing Component since we will never reuse a route
            this.router.routeReuseStrategy.shouldReuseRoute = function() {
                return false;
            };
    
            // ...
        }
    
        // ...
    }
    
    

    Last, in your routing components you can now handle param variables like this:

    import { Component, OnInit } from '@angular/core';
    import { ActivatedRoute } from '@angular/router';
    
    // ...
    
    @Component({
        // ...
    })
    export class MyComponent implements OnInit {
        // ...
    
        constructor(activeRoute: ActivatedRoute) {
    
        }
    
        public ngOnInit(): void {
            // Handle params
            const params = +this.activeRoute.snapshot.params;
    
            // ...
        }
    
        // ...
    }
    

    Common issues with this solution is that it isn't common. Also you are changing the default behavior of the Angular framework, so you can run into issues people wouldn't normally run into.

    Good thing is that all your code is synchronous and easier to understand.

    0 讨论(0)
  • 2020-11-28 03:39

    Angular 9

    I have used the following and it worked.

    onButtonClick() {
        this.router.routeReuseStrategy.shouldReuseRoute = function () {
            return false;
        }
        this.router.onSameUrlNavigation = 'reload';
        this.router.navigate('/myroute', { queryParams: { index: 1 } });
    }
    
    0 讨论(0)
  • 2020-11-28 03:39

    Create a different path for the same component in the routes array .

    const routes : Routes = [ { path : "app", component: MyComponent }, { path: "app-reload", component: MyComponent }];

    If the current URL is "app" then navigate using "app-reload" and vice versa.

    0 讨论(0)
  • 2020-11-28 03:40

    NgOnInit would be called once when an instance is created. For the same instance NgOnInit won't be called again. In order to call it it is necessary to destroy the created instance.

    0 讨论(0)
提交回复
热议问题