代码之家  ›  专栏  ›  技术社区  ›  MarcoLe

Angular 5-路由更改url但不导航

  •  3
  • MarcoLe  · 技术社区  · 7 年前

    目前我有三个不同的模块:

    • 应用程序模块--使用emtpy阵列根配置
    • 主页模块--具有主页组件的“”路径配置。用于搜索玩家
    • 玩家结果模块——显示搜索结果(玩家统计信息或错误页面)

    现在,在这个播放器搜索模块中,我有一个带有子组件的播放器搜索结果组件。其中一个子组件是包含列表的模态。如果我单击此列表项(播放器),它应该“导航”到父组件并更新其视图。但唯一更新的是url。

    有一个解决方法 window.location.href(url) 在导航方法更新url后重新记录页面。但我不喜欢变通办法。

    父组件非常类似于:

    export class PlayerSearchResultComponent implements OnInit, AfterViewInit {
    
     public isLoading = true;
      public searchValue: string;
      public playerResult: PlayerByPlayerTagType;
      public hasNoResultFound = false;
      public clanInfo: ClansByClantagType;
    
      constructor(private playerSearchService: PlayerSearchService,
                  private activatedRoute: ActivatedRoute,
                  private clanSearchService: ClanSearchService) {
      }
    
      ngOnInit(): void {
        this.activatedRoute.params.subscribe((params: Params) => {
          this.searchValue = params['playerId'];
        });
      }
    
      ngAfterViewInit() {
        this.playerSearchService.getPlayerByPlayerTag(this.searchValue).subscribe(player => {
            this.playerResult = player;
            if (!isUndefined(this.playerResult.clan)) {
              this.clanSearchService.getClanByClanTag(this.playerResult.clan.tag).subscribe((data: ClansByClantagType) => {
                this.clanInfo = data;
              });
            }
          }, () => {
            this.hasNoResultFound = true;
            this.isLoading = false;
          },
          () => this.isLoading = false);
      }
    }
    

    以及子组件:

    export class ClanModalComponent {
    
      @ViewChild('childModal') childModal: ModalDirective;
      @Input() playerResult: PlayerByPlayerTagType;
      @Input() clanInfo: ClansByClantagType;
    
    
      constructor(private router: Router) {
      }
    
      open() {
        this.childModal.show();
      }
    
      memberSearch(member) {
        this.childModal.hide();
        this.router.navigate(['search/' + member.tag]);
      }
    
    }
    

    播放器结果模块如下所示:

    const appRoutes: Routes = [
      {path: 'search/:playerId', component: PlayerSearchResultComponent}
    ];
    
    @NgModule({
      declarations: [
       ...
      ],
      imports: [
        ...
        RouterModule.forChild(
          appRoutes
        )],
      providers: [
         ...
      ],
      exports: []
    })
    export class PlayerResultModule {
    }
    
    2 回复  |  直到 5 年前
        1
  •  6
  •   David Ibl    7 年前

    因此,要基于路由参数进行加载,您必须订阅路由参数并加载数据。将不再处理ngAfterViewInit。因为组件在路线更改后不会再次加载!

    ngOnInit(): void {
        this.activatedRoute.params.subscribe((params: Params) => {
            this.searchValue = params['playerId'];
            this.playerSearchService
                .getPlayerByPlayerTag(this.searchValue)
                .subscribe(player => {
                    this.playerResult = player;
                    ...
                    ...
                });
         }
    }
    
        2
  •  0
  •   JWP    4 年前
    //browser is already on /pathName/oldID, 
    //this means our Routes are correct
     
     let newLocation = `/pathName/${newID}`;
     // override default re-use strategy
     this.router
        .routeReuseStrategy
        .shouldReuseRoute = function () {
            return false;
     };
     this.router
       .navigateByUrl(newLocation)
       .then(
       (worked) => {
            //works only because we hooked 
            //the routeReuseStrategy.shouldReuseRoute above
       },
       (error) => {
        debugger;
        }
     );
    

    我见过这个问题的次数比我愿意承认的要多,当我有一个父容器重用一个子组件时,通常会看到这个问题。

    • 默认情况下,父管线为xyz/。一切都很好。
    • 父级将路由更改为xyz/1,以显示1的个人id的详细信息
    • 父页面除了更改url外,什么都不做。

    这是因为Angular的默认路由重用策略不会重新加载页面!

    上面的代码修复了此默认行为,但必须将其放入适当的组件中才能获得从头开始的重新加载行为。

    请注意,还有其他选择。。。假设您希望保持组件重用的速度。在这种情况下,只需在已加载的组件中提供一个入口点来重置数据,让组件通过changeDetectorRef进行更改。DetectChanges()。