【问题标题】:Facing problems setting up breadcrumbs in angular面临以角度设置面包屑的问题
【发布时间】:2020-11-13 12:15:33
【问题描述】:

我从早上开始就在尝试解决与面包屑相关的问题,但仍然无法解决。我正在使用 Angular 10 并尝试使用角度路由来让面包屑在我的应用程序的每个页面的顶部工作。这是我的问题和代码:

问题: 我在应用程序中启用了延迟加载,目前面包屑似乎只能部分工作,因为我导航到的每个组件只显示一个面包屑。

例如当我按照下面的代码从图书馆导航到书籍组件时,我应该分别看到 'Library -> Book Foo''Library -> Book Bar' 作为面包屑。

但是当我导航到任何此类相关组件时,我只会看到像 'Book Foo''Book Bar' 这样的单个链接。

目录结构

app
  app.component.ts
  app.component.html
  app.component.scss
  app-routing.module.ts
    |
    |
    |
library
  LibraryComponent.component.ts
  LibraryComponent.component.html
  library-routing.module.ts
    |
    |
    |    
books
  BookFoo
    BookFooComponent.component.ts
    BookFooComponent.component.html
    BookFooComponent.component.scss
  BookBar
    BookBarComponent.component.ts
    BookBarComponent.component.html
    BookBarComponent.component.scss
  books.module.ts

books.module.ts

const routes: Routes = [

  { path: 'book-foo', 
    component: BookFooComponent,
    data: {
      breadcrumb:'Book Foo'
    }
  },

  { path: 'book-bar', 
    component: BookBarComponent,
    data: {
      breadcrumb:'Book Bar'
    }
  },

];

@NgModule({
  declarations: [
    BookFooComponent,
    BookBarComponent
  ],
  imports: [
    CommonModule,
    _SharedModule,
    RouterModule.forChild(routes)
  ],
  exports: [
    RouterModule
  ]
})
export class BooksModule { }

library-routing.module.ts

const routes: Routes = [
  { path: '', component: NestedroutingComponent,
    children:[
      { path: 'library', 
        component: LibraryComponent,
        data: {
          breadcrumb: 'Library'
        }, 
      },
      { path: 'books', loadChildren: () => import('../books/books.module').then(m => m.BooksModule) }
    ] 
  }
];

bread-crumb.service.ts(我从位于 here 的 SO 答案之一中遵循了这一点)

@Injectable()
export class BreadcrumbService {
  
  breadcrumbChanged = new EventEmitter<IBreadCrumb[]>(false)

  private breadcrumbs: IBreadCrumb[] = []

  constructor(private router: Router) {
    this.router.events.subscribe((routeEvent) => { this.onRouteEvent(routeEvent) })
  }

  onRouteEvent(routeEvent: Event) {
    if (!(routeEvent instanceof NavigationEnd)) { return }

    // Get the parent route snapshot
    let route = this.router.routerState.root.snapshot
    let url = ''

    const newCrumbs = []

    while (route.firstChild != null) {
      route = route.firstChild

      if (route.routeConfig === null) { continue }
      if (!route.routeConfig.path) { continue }

      url += `/${this.createUrl(route)}`

      // check until the routes contains title defined in it
      if (!route.data['breadcrumb']) { continue }

      const newCrumb = this.createBreadcrumb(route, url)
      newCrumbs.push(newCrumb)
    }

    // reassign breadcrumb list with new breadcrumb list
    this.breadcrumbs = newCrumbs
    this.breadcrumbChanged.emit(this.breadcrumbs)
  }

  createBreadcrumb(route: ActivatedRouteSnapshot, url: string): IBreadCrumb {
    return {
      displayName: route.data['breadcrumb'],
      url: url,
      route: route.routeConfig
    }
  }

  createUrl(route: any) {
    return route && route.url.map(function (s) { return s.toString() }).join('/')
  }
}

breadcrumbComponent.component.ts(此组件根据上面列出的服务获取面包屑)

@Component({
  selector: 'app-shared-breadcrumbs',
  templateUrl: './shared-breadcrumbs.component.html',
  styleUrls: ['./shared-breadcrumbs.component.scss']
})

export class SharedBreadcrumbsComponent implements OnInit {

  ngOnInit(): void {
    
  }

  breadcrumbs: IBreadCrumb[];

  constructor(private breadcrumbService: BreadcrumbService) {
    this.breadcrumbService.breadcrumbChanged.subscribe((crumbs: IBreadCrumb[]) => {
      this.onBreadcrumbChange(crumbs)
    })
  }

  private onBreadcrumbChange(crumbs: IBreadCrumb[]) {
    this.breadcrumbs = crumbs
  }
}

breadcrumbComponent.component.html(在所有页面上显示面包屑的模板)

<nav>
  <ol style="padding: 0%; display: flex;">              
    <li *ngFor="let breadcrumb of breadcrumbs" class="breadcrumb-item">
      <a [routerLink]="[breadcrumb.url]">{{ breadcrumb.displayName }}</a>
    </li>
  </ol>
</nav>

我尝试了什么?

我觉得我已经用尽了所有的选择,首先我尝试更改我的延迟加载结构以修改它以包含一些子组件,但一切都变得一团糟。我尝试更详细地阅读有关延迟加载的信息,但发现关于动态面包屑的信息非常少。

起初我尝试过this 教程,但遇到了同样的问题,点击后它也会导航到所有错误的路径。在这一点上,我很确定我将不得不改变我的一些路线,以便遵循父子关系,但不知道从哪里开始。

如果有人可以帮助我,我会很高兴。谢谢。

【问题讨论】:

  • 根据这个问题创建一个 StackBlitz 演示会非常有帮助。同时,您可以尝试将path: 'books' 路由添加为path: 'library' 路由的子节点

标签: angular typescript angular-routing


【解决方案1】:

另一种 获取面包屑的方法 - 是的,我知道这是不可扩展的 - 是“数据”是一个数组(我说“另一个”,因为这个答案与您的代码无关发布)

{ path: 'book-foo', 
    component: BookFooComponent,
    data: {
      breadcrumb:[{link:'../',text:'Library'},{text:'Book Foo'}]
    }
  },

那么,只需要

    <nav aria-label="breadcrumb">
      <ol >
        <li *ngFor="let bread of breadcrumbs|async;let last=last" [ngClass]="{'active':last}">
          <ng-container *ngIf="!last">
             <a routerLink="{{bread.link}}">{{bread.text}}</a>
             <span class="arrow right"></span>
          </ng-container>
          <span *ngIf="last">{{bread.text}}</span>
        </li>
      </ol>
    </nav>
export class BreadCrumsComponent{
    breadcrumbs = this.activatedRoute.data.pipe(map(res => res.breadcrumbs))
    constructor(private activatedRoute: ActivatedRoute) { }

}

好吧,我使用一个带有链接的对象数组,文本,可以只使用文本。

【讨论】:

  • 抱歉,回复晚了,但我最近通过使用 xng-breadcrumb 包中的&lt;xng-breadcrumb&gt;&lt;/xng-breadcrumb&gt; 并在组件模块中定义路由,如上面books.module.ts 中所述
  • @Dhruvify 你能创建 stackblitz 吗?我还面临设置复杂面包屑的问题。我在应用程序中有很多功能模块..所以需要详细展示。试图达到像Menu &gt; Users List&gt;View User&gt;XYZ
猜你喜欢
  • 2019-04-15
  • 1970-01-01
  • 2020-01-08
  • 1970-01-01
  • 1970-01-01
  • 2022-01-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多