使用导航防止Angular Router破坏组件

时间:2018-08-13 18:06:22

标签: angular5 angular-router

我在组件为created dynamically的环境中遇到了这个项目的问题。

简而言之,API将返回页面所需的所有组件,并使用Dynamic Component Loader创建所有必需的组件。还有一个解析器(ContentParserComponent)扩展了该类,并且正在管理第三方服务(在扩展的类之上)。

路线

...
{
    path: 'help-and-support',
    redirectTo: '/help-and-support/pay-monthly',
    pathMatch: 'full'
},
{
    path: 'help-and-support/:category',
    component: ContentParserComponent,
    pathMatch: 'full'
},
{
    path: 'help-and-support/:category/:subCategory',
    component: ContentParserComponent,
    pathMatch: 'full'
},
{
    path: 'help-and-support/:category/:subCategory/:slug',
    component: ContentParserComponent,
    pathMatch: 'full'
},
...

help-and-support页中,我们有一个容器组件,其中包含一个ngIf来显示商品组件(先前路线中的slug参数路线)或一个tabs component每个选项卡都包含一个手风琴组件。

帮助和支持组件

<app-help-article
    *ngIf="isArticleOpen && isLoaded"
    [article]="openArticle"
></app-help-article>

<app-help-tabs
    *ngIf="!isArticleOpen && isLoaded"
    [globalTabs]="globalTabs"
></app-help-tabs>

每次单击选项卡时,我们都需要导航到category参数路径,每次单击手风琴标题时,我们都需要导航到subCategory参数路径。 tabs组件使用的是Angular Material,而手风琴是一种自定义手风琴(它们都来自项目外部,都可以正常工作)。

选项卡组件通过Angular Material中的selectedTabChange事件来管理URL的更新。

标签组件

<!-- HTML -->
<mat-tab-group
    [selectedIndex]="updateIndex()"
    (selectedTabChange)="updateUrl($event)"
>
    ...
</mat-tab-group>


<!-- TS -->
updateUrl(e) {
    this.router.navigate([e.tab.content.viewContainerRef.injector.view.context.$implicit.navLink]);
}

对于手风琴标题,我们使用一个简单的click事件来更改URL。

手风琴组件

<!-- HTML -->
<div
    class="accordion-list__item--header"
    (click)="clickAccordion(subCategory.key, subCategory.value)"
>
    ...
</div>


<!-- TS -->
clickAccordion(subCategoryKey, subCategoryValue) {
    // Save current state, collapse the whole accordion and swap the current state
    const catCurrentState = subCategoryValue.active;
    this.collapseAll();
    subCategoryValue.active = !catCurrentState;

    let path = '';
    if (subCategoryValue.active) {
        path = this.navLink + '/' + subCategoryKey;
        this.activeSubcategory = subCategoryKey;
    } else {
        path = this.navLink;
    }

    this.router.navigate([path]);
}

this.navLink仅是类别的参考链接。

问题在于,使用Router上的navigate()方法实际上是重新初始化帮助和支持容器组件,从而导致每次在选项卡和手风琴标题上单击一次时都会刷新整个页面。

不是使用Location,尤其是使用location.replaceState()方法,而是整个页面都可以正常工作,而无需重新初始化容器组件。

但是,第二种解决方案在某种程度上导致了我们正在使用的breadcrumbs component中出现的问题,这些问题已被预订为导航事件,并且Location没有使用它们,因为它位于angular/common

所以,最后的问题是:为什么navigate()正在重新初始化容器组件?(在我看来,它不应该这样做...)

有没有更好的方法来做这些事情?

0 个答案:

没有答案