我的面包屑有什么问题 - Angular 11?
我正在尝试在我的 Angular 11 中使用 XNG-Breadcurmb 创建面包屑。我试图理解该文档并根据我的理解来实现它。
根据上面的 GIF,我缺少第二页和第三页之间的连接。
期望
用户列表 -->用户仪表板 -->完成的列表
当点击用户仪表板时,我应该返回用户仪表板页面,然后用户列表
当前行为
当我单击卡片(单击已完成列表 btn 或未完成列表 btn)时,用户仪表板消失了。我不知道我失踪在哪里。
团队,对没有添加 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 { }
客户.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 { }
Customer-list-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]);
}
}
Customer-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>
Customer-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>
Customer-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]);
}
}
}
Customer-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>
尝试一下这个原生解决方案,但我又没能成功,因为我没有很好地理解路由器事件(那是我的错)。
所以请求大家帮助我,
谢谢
I'm trying to create breadcrumbs using XNG-Breadcurmb, in my Angular 11. I tried to understand the document and implement it based on my understanding.
As per the above GIF, I'm missing connection between 2nd and third page.
Expectation
Users List --> User Dashboard --> Completed List
When click on User Dashboard I should go back on User Dashboard page then User List
Current behavior
when i click on cards (either click on completed list btn or in-completed list btn), User Dashboard disappeared. i don't know where im missing.
Team, appologize for not adding stackblitz, due to some reason I'm blocked to access stackblitz or any code sandbox
so far i have
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 { }
Customer-list-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]);
}
}
Customer-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>
Customer-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>
Customer-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]);
}
}
}
Customer-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>
And given a try with this native solution , but again i couldn't make it because i didn't get good understanding about router event(That's my fault).
So requesting all to help me,
Thanks
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
该库(默认情况下)利用路由层次结构来设置面包屑。这是目前您的路线层次结构的可视化
路由层次结构
如您所见,用户仪表板既不是后代完成列表或任何
模块
或组件
路线。最简单的解决方案是将
CustomerDashboardComponent
、CustomerTabSelectionComponent
、CompletedUsersComponent
和IncompleteUsersComponent
重构为另一个组件的子组件。您最终将得到以下路由结构:注意:如果父路由路径有空路径,则您不需要在任何具有空路径的后代上使用面包屑。如果两者均已定义,则子级(具有空路径)将覆盖父级 来源
The library (by default) utilizes the routes hierarchy to set up the breadcrumbs. Here is a visualization of your routes hierarchy at the moment
routes hierarchy
As you can see, User Dashboard is neither a descendant of Completed List nor any
module
orcomponent
route.The simplest solution is to refactor
CustomerDashboardComponent
,CustomerTabSelectionComponent
,CompletedUsersComponent
, andIncompleteUsersComponent
to be children of another component . You will end up with following routes structure:Note: you don't need breadcrumb on any descendant with empty path if parent route path has one. If both are defined, the child (with empty path) will overwrite the parent one source