【问题标题】:Angular 5 - Routing changes url but doesn't navigateAngular 5 - 路由更改 url 但不导航
【发布时间】:2018-03-25 15:31:58
【问题描述】:

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

  • App 模块 -- 使用 emtpy 数组根配置
  • 主页模块 -- 带有主页 comp 的 '' 路径配置。寻找球员
  • 玩家结果模块 -- 显示搜索结果(玩家统计信息或错误页面)

现在在这个播放器搜索模块中,我有一个带有子组件的播放器搜索结果组件。其中一个子组件是一个带有列表的模式。如果我单击此列表项(播放器),它应该“导航”到父组件并更新其视图。但唯一更新的是 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 {
}

【问题讨论】:

  • 更改路线时您期望什么?我猜 playerId 改变了?
  • 更改路由时,我希望调用父组件并更新父视图。

标签: angular typescript url angular2-routing


【解决方案1】:

因此,要根据路由参数进行加载,您必须订阅 Route 参数并加载数据。 ngAfterViewInit 将不再被处理。因为路由改变后组件不再加载!

ngOnInit(): void {
    this.activatedRoute.params.subscribe((params: Params) => {
        this.searchValue = params['playerId'];
        this.playerSearchService
            .getPlayerByPlayerTag(this.searchValue)
            .subscribe(player => {
                this.playerResult = player;
                ...
                ...
            });
     }
}

【讨论】:

  • 天哪!它的工作原理没想到它会依赖它,但现在我在控制台中抛出一个错误 this._subscribe is not a fuction
  • 你在哪里称呼这个._subscribe?我在任何地方都看不到。
【解决方案2】:
//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() 进行更改。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-05-16
    • 2018-05-19
    • 1970-01-01
    • 2020-05-13
    • 2018-10-17
    • 2016-08-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多