每次第一个字母更改时,将大写字母添加到有角的列表中

时间:2018-11-23 11:41:08

标签: angular

我有一个建筑师名单。 每当建筑师以一个新字母开头时,我都应该添加一个字母来构建建筑师列表:

示例:

A

ABC建筑师 北极建筑师

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>

如何在不修改列表的情况下添加字母?

备注:字母不应该链接。

4 个答案:

答案 0 :(得分:0)

您可以通过在Component中编写小函数并从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>

答案 1 :(得分:0)

这是闪电击中的样本堆栈以及类似的数据数组。

在模板中,可以通过使用索引并减去一个来获得数组中的上一项。

  <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

答案 2 :(得分:0)

您可以在组件中使用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()中)仅调用一次该方法,而无需不断调用该组件。

答案 3 :(得分:-1)

您可以创建一个方法,该方法将返回一个布尔值以决定是否应显示占位符字母。这应该通过将每个架构师名称的第一个字符与Component的一个属性进行比较来完成。还应该确保在列表中以新字母开头的名称后立即更新该属性。

尝试一下:

<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;
    }
  }
}

这是您推荐的Sample StackBlitz