我有一个架构师列表。每当建筑师以一个新字母开头时,我都应该添加一个字母,以构建建筑师列表:
示例:
ABC建筑师Arctical Architects
B
波士顿建筑师事务所
D
荷兰建筑师
等等。
我的实际代码:
<ul class="architect-list">
<li *ngFor="let architect of architects">
<div class="single-architect" (click)="selectArchitect(architect.title)" [innerHTML]="architect.title">
</div>
</li>
</ul>
如何在不修改列表的情况下添加字母?
备注:信件不应链接。
您可以创建一个方法,该方法将返回一个布尔值,以决定是否应显示占位符字母表。这应该通过将每个架构师名称的第一个字符与组件上的属性进行比较来实现。它还应该确保在列表中开始使用新字母表的名称后立即更新该属性。
试试看:
<ul class="architect-list">
<ng-container *ngFor="let architect of architects">
<ng-container *ngIf="checkIfNew(architect.title)">
{{ architect.title.charAt(0).toUpperCase() }}
</ng-container>
<li>
<div class="single-architect" (click)="selectArchitect(architect.title)" [innerHTML]="architect.title">
</div>
</li>
</ng-container>
</ul>
组件类别:
import { Component } from '@angular/core';
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
})
export class AppComponent {
currentAlphabet;
architects = [...];
checkIfNew(title: string) {
if(this.currentAlphabet === title.charAt(0).toLowerCase()) {
return false;
} else {
this.currentAlphabet = title.charAt(0).toLowerCase();
return true;
}
}
}
这是一个样品堆栈闪电供您参考。
您可以通过在组件中编写小函数并从HTML中调用它来实现这一点。但同时,从性能的角度来看,这不是最佳解决方案,您需要将此逻辑转移到自定义指令。答案是这样的。
工作stackblitz示例如下。
code required in component
checkLetter(architect: any, i: number) {
let Initial = '';
if (i === 0) {
Initial = this.architects[0].title.charAt(0);
} else {
if (this.architects[i].title.charAt(0) === this.architects[i - 1].title.charAt(0)) {
Initial = '';
}
else {
Initial = this.architects[i].title.charAt(0);
}
}
return Initial;
}
code required in html
<ul class="architect-list">
<ng-container *ngFor="let architect of architects; let i = index">
<ng-container>
{{checkLetter(architect, i)}}
</ng-container>
<li>
<div class="single-architect" (click)="selectArchitect(architect.title)" [innerHTML]="architect.title">
</div>
</li>
</ng-container>
下面是我通过的一个示例堆栈闪电战,以及一个类似的数据数组。
在模板中,您可以通过使用索引并减去一来获得数组中的前一项。
<ul class="genre-list">
<li *ngFor="let genere of musicGeneres; let index = index;">
<div *ngIf="isStartingAlaphet(genere, musicGeneres[index - 1])">
{{ genere[0] }}
</div>
<div [innerHTML]="genere">
</div>
</li>
</ul>
然后有一个小的纯函数,它首先检查前一个项目是否存在,如果不存在,则我们在A
上显示它。如果不存在则将当前项目的第一个字母与前一个字母进行比较。
isStartingAlaphet(current, previous){
// if there is no previous one then a
if(!previous){
return current[0]
}
return current[0] !== previous[0]
}
这取决于你的列表是按字母顺序排列的,但它也会保留任何混乱的代码,因为你的组件必须"跟踪"前一项并依赖于不纯净的函数。
要将这种类型的解决方案用于更复杂的阵列,只需输入标题:
<div *ngIf="isStartingAlaphet(architect.title, architects[index - 1]?.title)">
{{ architect.title[0] }}
</div>
https://stackblitz.com/edit/angular-mw7tp2
您可以在组件中使用reduce,假设原始架构师的列表是一个数组:
const objectkeys = Object.keys;
const list = ['Aaarchitext', 'Brand New Architect', 'Clydesdale Architect'];
const newList = this.getReorderedList();
function getReorderedList(): void {
return list.reduce((grp, a, b) => {
if (!grp[a.slice(0,1)]) {
grp[a.slice(0,1)] = [];
}
grp[a.slice(0,1)].push(a);
return grp;
}, {});
}
然后在您的模板中:
<ul class="architect-list">
<ng-container *ngFor="let firstLetter of objectkeys(newList)">
<li>{{ firstLetter }}</li>
<ng-container *ngFor="let architect of newList[firstLetter]">
<div
class="single-architect"
(click)="selectArchitect(architect.title)"
[innerHTML]="architect.title">
</div>
</ng-container>
</ng-container>
</ul>
这应该能解决你的问题。您还只需要在开始时调用该方法一次(即在ngOnInit((中(,而不需要对组件进行常量调用。