我有两个组件和一个服务。我认为问题在于,当我从一个路由组件的视图中点击出不同组件(matMenu和输入字段)的元素时,路由组件似乎会重新呈现自己。如果所述被路由的组件正在生成错误(在这种情况下是GET错误),则这实际上仅成为问题(至少到目前为止)。因此,通过重复相同的操作,控制台可能会充满大量错误。我想了解在这种情况下会发生什么,以及如何进行优化。
组件A使用matMenu,
<nav class="navbar">
<div class="d-flex justify-content-start align-items-center">
<a mat-icon-button href="" class="icon-button">
<mat-icon>home</mat-icon>
</a>
<span fxHide.gt-sm>
<button mat-icon-button class="icon-button" [matMenuTriggerFor]="menu">
<mat-icon>menu</mat-icon>
</button>
</span>
<span fxHide.lt-md>
<button type="button" class="btn btn-primary" [matMenuTriggerFor]="menu"><b>Alkatrészek</b></button>
<button type="button" class="btn btn-primary"><b>Szolgáltatások</b></button>
<button type="button" class="btn btn-primary"><b>Vásárlási információk</b></button>
<button type="button" class="btn btn-primary"><b>Elérhetőség</b></button>
</span>
</div>
<div>
<mat-menu #menu="matMenu">
<button mat-menu-item *ngFor="let item of kategoriaList$ | async"
(click)="setCategoryPage(item.nev)">{{item.nev}}</button>
</mat-menu>
<ng-container *ngIf="alkatreszList$">
<app-search-bar #searchBar [alkatreszList$]="alkatreszList$"></app-search-bar>
</ng-container>
</div>
</nav>
在哪里
setCategoryPage(category: string) {
if (category !== this.categoryPageService.getCategory()) {
this.categoryPageService.setCategory(category);
this.categoryPageService.setShowCategoryPage(true);
}
}
正在调用服务
export class CategoryPageService {
private showCategoryPageSubject = new BehaviorSubject<boolean>(false);
showCategoryPage$ = this.showCategoryPageSubject.asObservable();
category: string = '';
getCategory(): string {
return this.category;
}
setCategory(categoryIn: string) {
this.category = categoryIn;
}
setShowCategoryPage(showCategoryPage: boolean) {
this.showCategoryPageSubject.next(showCategoryPage);
}
constructor() { }
}
然后,从组件A到组件B进行路由
<body>
<img *ngIf="!(showCategoryPage$ | async)" src="assets\20170822_180636.jpg">
<app-category-page *ngIf="showCategoryPage$ | async"></app-category-page>
</body>
在组件B中,网格中有一个carousel,其中填充了来自数据库的数据(就像在组件A中一样)
async ngOnInit() {
this.alkatreszList$ = this.service.getAlkatreszList();
this.kategoriaList$ = this.service.getKategoriaList();
this.autoTipusList$ = this.service.getAutoTipusList();
this.kategoria.push(this.categoryService.getCategory());
this.kategoria = this.kategoria.map((value: string) => value.trim().replace(/\s+/g, ' '));
this.searchService.setCategoryFilter(this.kategoria);
this.filteredAlkatreszek$ = this.searchService.getFilteredAlkatreszek(this.alkatreszList$);
this.showCategoryPage$ = this.categoryService.showCategoryPage$;
}
calculateRows(items: any[]): any[][] {
const maxColumns = 6;
const numRows = Math.ceil(items.length / maxColumns);
const rows: any[][] = [];
for (let i = 0; i < numRows; i++) {
rows.push(items.slice(i * maxColumns, (i + 1) * maxColumns));
}
return rows;
}
getRowItems(items: any[], rowIndex: number): any[] {
const maxColumns = 6;
const rowItems = items.slice(rowIndex * maxColumns, (rowIndex + 1) * maxColumns);
return rowItems;
}
在模板中
<ng-container *ngIf="showCategoryPage$ | async">
<div>
<p>IT WORKS</p>
</div>
<div class="container text-center" *ngIf="(filteredAlkatreszek$ | async) as filteredAlkatreszek">
<div class="row" *ngFor="let row of calculateRows(filteredAlkatreszek); let i = index;">
<ng-container>
<div class="col" *ngFor="let item of getRowItems(filteredAlkatreszek, i)">
<div id="imageCarouselCategoryPage" class="carousel slide" data-bs-ride="false">
<div *ngIf="item.kepek.split(';').length > 1" class="carousel-indicators">
<button type="button" [attr.data-bs-target]="'#imageCarouselCategoryPage'" [attr.data-bs-slide-to]="i" [class.active]="i === 0" *ngFor="let img of item.kepek.split(';');
let i = index" [attr.aria-label]="'Slide ' + (i + 1)"></button>
</div>
<div class="carousel-inner">
<div class="carousel-item active" [class.active]="i === 0" *ngFor="let img of item.kepek.split(';'); let i = index">
<img class="d-block w-100" [src]="'https://localhost:7094/images/' + img" style="max-height: 100vh; max-width: 100%;">
<div class="carousel-caption d-none d-md-block">
<h5>{{item.nev}}</h5>
<p>{{item.ar}}</p>
</div>
</div>
<button class="carousel-control-prev" type="button" data-bs-target="#imageCarouselCategoryPage" data-bs-slide="prev">
<span class="carousel-control-prev-icon" aria-hidden="true"></span>
<span class="visually-hidden">Previous</span>
</button>
<button class="carousel-control-next" type="button" data-bs-target="#imageCarouselCategoryPage" data-bs-slide="next">
<span class="carousel-control-next-icon" aria-hidden="true"></span>
<span class="visually-hidden">Next</span>
</button>
</div>
</div>
</div>
</ng-container>
</div>
</div>
</ng-container>
我提到的输入字段本身从组件A路由到另一个组件(组件C)。
<ng-container *ngIf="alkatreszList$">
<app-search-bar #searchBar [alkatreszList$]="alkatreszList$"></app-search-bar>
</ng-container>
那么,为什么当单击组件A /组件C中的元素时,组件B会重新呈现(如果这是发生的情况)?这种行为与变化检测有什么关系?
1条答案
按热度按时间jbose2ul1#
Angular的更改检测在事件发生时触发。当更改检测被触发时,Angular会检查组件的模板是否有任何更新,并在必要时应用它们。https://angular.io/api/core/ChangeDetectionStrategy
使用
ChangeDetectionStrategy.OnPush
或本地化更改检测。另外,通过使用不可变的数据结构,确保组件A、B和C之间共享的数据是不可变的。
在最新的版本(16)中,Angular 还引入信号https://angular.io/guide/signals,并且在下一版本中引入信号分量。