Angular 路由器导航在同一页面时不调用ngOnInit

Angular 路由器导航在同一页面时不调用ngOnInit,angular,navigateurl,ngoninit,Angular,Navigateurl,Ngoninit,我正在呼叫路由器。使用一些查询字符串参数在同一页面上导航。在这种情况下,ngOnInit()不会调用。是默认设置还是我需要添加其他内容?您可以插入ActivatedRoute并订阅params 构造函数(路由:ActivatedRoute){ route.params.subscribe(val=>{ //把‘ngOnInit’的代码放在这里 }); } 路由器仅在导航到其他路由时销毁和重新创建组件。当仅更新路由参数或查询参数但路由相同时,不会销毁和重新创建组件 强制重新创建组件的另一种方法是

我正在呼叫路由器。使用一些查询字符串参数在同一页面上导航。在这种情况下,
ngOnInit()
不会调用。是默认设置还是我需要添加其他内容?

您可以插入
ActivatedRoute
并订阅
params

构造函数(路由:ActivatedRoute){
route.params.subscribe(val=>{
//把‘ngOnInit’的代码放在这里
});
}
路由器仅在导航到其他路由时销毁和重新创建组件。当仅更新路由参数或查询参数但路由相同时,不会销毁和重新创建组件


强制重新创建组件的另一种方法是使用自定义重用策略。另请参见(似乎没有太多可用信息,但如何实现它)

ngonit
在创建实例时将被调用一次。对于同一个实例,
将不再调用NgOnInit
。为了调用它,必须销毁创建的实例。

考虑将ngOnInit中的代码移动到ngAfterViewInit中。
后者似乎在路由器导航时被调用,在这种情况下应该会对您有所帮助。

您可以调整路由器上的重用策略

constructor(private router: Router) {
    // override the route reuse strategy
    this.router.routeReuseStrategy.shouldReuseRoute = function() {
        return false;
    };
}

这个问题可能是因为您没有使用Ngondestory终止订阅。下面是如何完成的

  • 引入以下rxjs订阅导入。
    从'rxjs/Subscription'导入{Subscription}

  • 将OnDestory添加到您的Angular Core导入。
    从'@angular/core'导入{Component,OnDestroy,OnInit}

  • 将OnDestory添加到导出类。
    导出类DisplayComponent实现OnInit、OnDestroy{

  • 在导出类下为组件上的每个订阅创建一个对象属性,其值为Subscription from rxjs。
    myVariable:Subscription;

  • 将订阅的值设置为MyVariable:Subscriptions。
    this.myVariable=this.rmanagerService.getRPDoc(books[i].books.id).subscribe(value=>{});

  • 然后在ngOninit的正下方放置ngOnDestory()生命周期钩子,并将其放入订阅的unsubscribe语句中。如果有多个,请添加更多
    ngondestory(){
    this.myVariable.unsubscribe();
    }


  • 您可能需要重新加载页面吗?这是我的解决方案:我已更改了@NgModule(在我的情况下,在app routing.module.ts文件中):


    当您想在同一页上导航并调用ngOnInit()时,您会喜欢这样做,例如

    this.router.navigate(['category/list',category])
    。然后(()=>window.location.reload());

    为routes数组中的同一组件创建不同的路径

    常量路由:路由=[{ 路径:“应用程序”, 成分:MyComponent }, { 路径:“应用程序重新加载”, 成分:MyComponent }])

    如果当前URL为“应用程序”
    然后使用“应用程序重新加载”导航,反之亦然。

    这是本页上的最佳想法集合,提供了更多信息

    解决方案1-使用params订阅:

    教程:

    文件:

    在每个使用参数变量的路由组件中,包括以下内容:

    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();
        }
    }
    
    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;
            };
    
            // ...
        }
    
        // ...
    }
    
    
    这段代码的一些常见问题是,订阅是异步的,处理起来可能比较棘手。此外,您不能忘记取消对Ngondestory的订阅,否则可能会发生不好的事情

    好消息是,这是处理此问题的最有文档记录和最常用的方法。这样做还可以提高性能,因为您可以重用模板,而不是每次访问页面时都销毁和重新创建模板

    解决方案2-应重用远程/远程导航:

    文件:

    文件:

    文件:

    查找
    RouterModule.forRoot
    在项目中的位置(通常在app-routing.module.ts或app.module.ts中找到):

    然后在AppComponent中添加以下内容:

    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();
        }
    }
    
    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;
            };
    
            // ...
        }
    
        // ...
    }
    
    
    最后,在路由组件中,您现在可以处理如下参数变量:

    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;
    
            // ...
        }
    
        // ...
    }
    
    此解决方案的常见问题是它不常见。此外,您正在更改Angular框架的默认行为,因此您可能会遇到人们通常不会遇到的问题

    好消息是,您的所有代码都是同步的,更容易理解。

    9 我使用了下面的方法,效果很好

    onButtonClick() {
        this.router.routeReuseStrategy.shouldReuseRoute = function () {
            return false;
        }
        this.router.onSameUrlNavigation = 'reload';
        this.router.navigate('/myroute', { queryParams: { index: 1 } });
    }
    

    在你的导航方法上

    this.router.routeReuseStrategy.shouldReuseRoute = () => false;
    this.router.onSameUrlNavigation = 'reload';
    this.router.navigate(['/document'], {queryParams: {"search": currentSearch}});
    

    我也遇到过同样的问题,另外我得到了警告:

    你忘记调用'ngZone.run()了吗`
    
    现场提供了最佳解决方案:

    从'@angular/Router'导入{Router};
    从“@angular/core”导入{NgZone};
    ...
    建造师(
    私人ngZone:ngZone,
    专用路由器:路由器
    ){ }
    重定向(到){
    //使用ngZone调用,以便调用组件的ngonnit
    this.ngZone.run(()=>this.u路由器.导航([to]);
    }
    
    这并不是真的发生。这将启动页面上每个组件的ngInit。好吧,@Pascal,你强迫我登录到SO只是为了投票给你的答案。我想补充一点,在Angular 6中,你还必须在ameurlNavigation上添加
    :reload'
    到config对象中,如:
    RouterModule.forRoot(appRoutes,{onSameUrlNavigation:'reload'})
    。但是,对于任何其他角度的版本,我都不能说。@Hildy,我不得不这样做:)谢谢@Pascal!如果你喜欢lambda,你可以这样做。router.RouterUseStrategy.shouldReuseRoute=()=>false;@Swaprks我创建了一个routing.module.ts,并将代码如下所示constructor@Swaprks..我有一个类似的问题,我想尝试一下你上面的答案。但是作为一个这个领域的初学者,这并不能告诉我太多。我应该在代码中的什么地方放置这个代码段?我应该在代码段中更改什么吗(例如´functi