我的面包屑有什么问题 - Angular 11?

What is wrong with my breadcrumbs - Angular 11?

我正在尝试使用 XNG-Breadcurmb 在我的 Angular 11 中创建面包屑。我试图理解文档并根据我的理解实现它。

根据上面的 GIF,我缺少第 2 页和第 3 页之间的连接。

预期

用户列表 --> 用户仪表板 --> 完成列表

当点击用户仪表板时,我应该返回用户仪表板页面然后用户列表

当前行为

当我单击卡片时(单击已完成列表按钮或未完成列表按钮),用户仪表板消失了。我不知道我哪里不见了。

团队,很抱歉没有添加 stackblitz,由于某些原因我被阻止访问 stackblitz 或任何代码沙箱

到目前为止我有

app.routing.ts

import { HomeComponent } from './components/home/home.component';
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
const routes: Routes = [
    { path: '', pathMatch: 'full', redirectTo: '', component: HomeComponent },
    {
        path: 'home', component: HomeComponent,
        data: {
            breadcrumb: {
                label: 'my home',
                info: 'home',
                routeInterceptor: (routeLink) => {
                    console.log(routeLink);
                    return routeLink;
                },
            },
        },
    },
    {
        path: 'customers',
        loadChildren: () => import('./feature/customer/customer.module').then(m => m.CustomerModule),
        data: {
            breadcrumb: {
                label: 'Users List',
            },
        },
    }
];

@NgModule({
    imports: [RouterModule.forRoot(routes)],
    exports: [RouterModule]
})
export class AppRoutingModule { }

customer.routing.module.ts

import { IncompleteUsersComponent } from './components/incomplete-users/incomplete-users.component';
import { CompletedUsersComponent } from './components/completed-users/completed-users.component';
import { CustomerTabSelectionComponent } from './components/customer-tab-selection/customer-tab-selection.component';
import { CustomersListComponent } from './components/customers-list/customers-list.component';
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { CustomerDashboardComponent } from './components/customer-dashboard/customer-dashboard.component';

const routes: Routes = [
  {
    path: '', component: CustomersListComponent,
    /*  data: {
       breadcrumb: 'Customer List'
     } */
    data: {
      breadcrumb: {
        disable: true,
      },
    },
  },
  {
    path: 'dashboard/:id', component: CustomerDashboardComponent, data: {
      breadcrumb: 'User Dashboard'
    }
  },
  {
    path: 'user-tab/:id', component: CustomerTabSelectionComponent, data: {
      breadcrumb: 'Users tab'
    },
  },
  {
    path: 'cmp-users/:id', component: CompletedUsersComponent, data: {
      breadcrumb: 'Completed Users list'
    }
  },
  {
    path: 'icmp-users/:id', component: IncompleteUsersComponent, data: {
      breadcrumb: 'In-completed Users list'
    }
  }

];

@NgModule({
  imports: [RouterModule.forChild(routes)],
  exports: [RouterModule]
})
export class CustomerRoutingModule { }

客户列表-component.ts

import { UsersService } from './../../users.service';
import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';

@Component({
  selector: 'app-customers-list',
  templateUrl: './customers-list.component.html',
  styleUrls: ['./customers-list.component.scss']
})
export class CustomersListComponent implements OnInit {

  userList;
  constructor(private userService: UsersService, private router: Router) { }

  ngOnInit(): void {
    this.loadUsers();
  }

  loadUsers(): void {
    this.userService.getUsersList().subscribe((response) => {
      if (response) {
        this.removeDuplicateUsers(response);
      }
    }, err => {
      console.log('Error', err);
    });
  }

  removeDuplicateUsers(data): void {
    this.userList = data.filter((v, i, a) => a.findIndex(t => (t.userId === v.userId)) === i);
    console.log('user list', this.userList);
  }

  gotoUserDashboard(item): void{
    console.log('href clicked', item);
    this.router.navigate(['customers/dashboard/' + item.userId]);
  }

}

客户-list.html

<div class="wrapper">
    <div class="lbl-container">
        <span class="lbl">User Id</span>
        <span class="lbl">Status</span>
    </div>
    <div class="data-container" *ngFor="let user of userList">        
        <span class="lbl"><a href="javascript:void(0);" (click)="gotoUserDashboard(user)">{{user.userId}}</a></span>      
        <span class="lbl">{{user.completed === false ? 'Not Complete': 'Completed'}}</span>
    </div> 
</div>

客户-dashboard.ts

import { Component, OnInit } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { UsersService } from '../../users.service';

@Component({
  selector: 'app-customer-dashboard',
  templateUrl: './customer-dashboard.component.html',
  styleUrls: ['./customer-dashboard.component.scss']
})
export class CustomerDashboardComponent implements OnInit {
  totalComplete;
  totalInComplete;
  userInfo;
  constructor(private activatedRoute: ActivatedRoute, private router: Router, private userService: UsersService) {
    this.activatedRoute.params.subscribe(data => {
      const userId = data.id;
      this.getUserInfoByUserId(userId);
      console.log(userId);
    });
  }

  ngOnInit(): void {
  }

  getUserInfoByUserId(userId): void {
    console.log('user data', userId);
    this.userService.getUserByID(userId).subscribe((response) => {
      if (response) {
        console.log(response);
        this.userInfo = response;
        this.totalComplete = response.filter((t) => t.completed === true).length;
        this.totalInComplete = response.filter((f) => f.completed === false).length;
        console.log('totalComplete', this.totalComplete);
        console.log('total In-Complete', this.totalInComplete);
      }
    }, err => {
      console.log(err);
    });
  }

  gotoUserbyStatus(e): void{
    console.log('click', this.userInfo);
    console.log('event', e.target.value);
    const extra =  { tab: e.target.value, userId : this.userInfo[0].userId };
    // this.router.navigate(['customers/customer-tab/' + this.userInfo[0].userId], { state: extra });
    this.router.navigate(['customers/user-tab/' + this.userInfo[0].userId], { state: extra });
  }
}

customer.dashboard.html

<div class="task-wrapper" >
    <div class="completed">
        <h2>Completed</h2>
        <h4>{{totalComplete}}</h4>
        <div class="list">
            <button (click)="gotoUserbyStatus($event)" value="completeLst">Completed List</button>
        </div>
    </div>
    <div class="incompleted">
        <h2>In-Completed</h2>
        <h4>{{totalInComplete}}</h4>
        <div class="list">
            <button (click)="gotoUserbyStatus($event)" value="inCompleteLst">In-Completed List</button>
        </div>
    </div>
</div>

客户-tab.ts

import { Component, OnInit } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { UsersService } from '../../users.service';

@Component({
  selector: 'app-customer-tab-selection',
  templateUrl: './customer-tab-selection.component.html',
  styleUrls: ['./customer-tab-selection.component.scss']
})
export class CustomerTabSelectionComponent implements OnInit {

  userId;
  tabFocus = '';
  constructor(private activatedRoute: ActivatedRoute, private router: Router, private userService: UsersService) {
    this.activatedRoute.params.subscribe(data => {
      if (data && data.id){
        const userId =  data.id;
        console.log('params', userId);
      }
    });
    const routerData = this.router.getCurrentNavigation().extras.state;
    console.log('extra', routerData);
    this.userId = routerData.userId;
    this.tabFocus = routerData.tab;
  }

  ngOnInit(): void {
  }

  onTabClick(event): void{
    console.log('tab click event', event.target.value);
    const focusTab = event.target.value;
    if (focusTab === 'completed'){
      // this.router.navigate(['customers/customer-tab/' + this.userInfo[0].userId], { state: extra });
      this.router.navigate(['customers/cmp-users/' + this.userId]);
    } else if (focusTab === 'incompleted'){
      this.router.navigate(['customers/icmp-users/' + this.userId]);
    }
  }
}

客户-tab.html

<div class="container-fluid">
    <div class="row">
        <ul class="nav nav-tabs" id="myTab" role="tablist">
            <li class="nav-item" role="presentation">
                <button class="nav-link" id="completed-tab" data-bs-toggle="tab" data-bs-target="#completed"
                    type="button" role="tab" aria-controls="completed" aria-selected="true"
                    [ngClass]="[tabFocus === 'completeLst' ? 'active' : '']" (click)="onTabClick($event)"
                    value="completed">completed</button>
            </li>
            <li class="nav-item" role="presentation">
                <button class="nav-link" id="incompleted-tab" data-bs-toggle="tab" data-bs-target="#incompleted"
                    type="button" role="tab" aria-controls="incompleted" aria-selected="false"
                    [ngClass]="[tabFocus === 'inCompleteLst' ? 'active' : '']" (click)="onTabClick($event)"
                    value="incompleted">incompleted</button>
            </li>

        </ul>
        <div class="tab-content" id="myTabContent">
            <div class="tab-pane fade" id="completed" role="tabpanel" aria-labelledby="completed-tab"
                [ngClass]="[tabFocus === 'completeLst' ? 'show active' : '']">
                <app-completed-users></app-completed-users>
            </div>
            <div class="tab-pane fade" id="incompleted" role="tabpanel" aria-labelledby="incompleted-tab"
                [ngClass]="[tabFocus === 'inCompleteLst' ? 'show active' : '']">
                <app-incomplete-users></app-incomplete-users>
            </div>

        </div>
    </div>
</div>

并试了一下 native solution ,但我还是没能做到,因为我对路由器事件没有很好的理解(那是我的错)。

所以请求大家帮助我,

谢谢

库(默认情况下)利用路由层次结构来设置面包屑。这是目前您的路线层次结构的可视化 routes hierarchy

如您所见,用户仪表板既不是已完成列表的后代,也不是任何modulecomponent 路线.

最简单的解决方案是将 CustomerDashboardComponentCustomerTabSelectionComponentCompletedUsersComponentIncompleteUsersComponent 重构为另一个组件的子组件。您最终将得到以下路由结构:

const routes: Routes = [
  {path: '', component: CustomersListComponent},
  {
    path: 'users', component: UsersComponent,
    data: { breadcrumb: 'User Dashboard' },
    children: [
      {path: '', redirectTo: 'dashboard/:id', pathMatch: 'exact'},
      {
        path: 'dashboard/:id', component: CustomerDashboardComponent
      },
      {
        path: 'user-tab/:id', component: CustomerTabSelectionComponent,
        data: { breadcrumb: 'Users tab' },
      },
      {
        path: 'cmp-users/:id', component: CompletedUsersComponent,
        data: { breadcrumb: 'Completed Users list' }
      },
      {
        path: 'icmp-users/:id', component: IncompleteUsersComponent,
        data: { breadcrumb: 'In-completed Users list' }
      }
    ]
  }

];

注意:如果父路由路径有一个,则您不需要在任何具有空路径的后代上使用面包屑。如果两者都已定义,则子项(空路径)将覆盖父项 source