带有键值管道的角度NgFor显示不正常

时间:2019-02-12 23:16:04

标签: angular typescript rxjs google-cloud-firestore ngfor

我正试图做一个六面体。因此,我从firestore中检索了一个十六进制集合,按ID对其进行了排序,将其移至10行(因此前10个进入“ row0”,接下来的10个进入“ row1”,依此类推),并使用ngFor显示它们

问题是当我显示它们时,我得到了:

row0

第1行

第10行

row11

第2行

第3行

第4行

第5行

第6行

第7行

第8行

第9行

所以我显然缺少了一些东西。我认为它们是乱序的,但是我正在console.logging行并按预期顺序看到它们:

行[row0:Array(10),row1:Array(10),row2:Array(10),row3:Array(10),row4:Array(10),...]对象

我可以看到该顺序似乎基于“行”之后的第一个数字,但不确定为什么。任何指针将不胜感激!

TS:

服务

export class FirestoreService {

  constructor(private db:AngularFirestore) { }

  getHexes(){
    let hexRows = []

    let hexes = this.db.collection('hexes', ref=> ref.orderBy('id')).valueChanges().subscribe(data => {
      data.forEach((hex, index) => {
        let rowNum = Math.floor(index / 10)

        if(hexRows[`row${rowNum}`] == undefined){
          hexRows[`row${rowNum}`] = []
        }
        hexRows[`row${rowNum}`].push(hex)
      })
      console.log('Rows', hexRows, typeof hexRows);
    })

    return hexRows
  }

组件

ngOnInit() {
    this.hexRows = this.afs.getHexes()
  }

HTML:

组件

<div *ngFor="let row of hexRows | keyvalue">
  {{row.key}}
</div>

更新

因此,在Deborah的领导下,我尝试使用comparefn并意外地“修复了它”。我做了一个名为'orderByRowNum'的快速测试函数,当我检查它是否运行时,看起来像按预期顺序排列了列表:

TS:

orderByRowNum = (a,b) => {
    console.log('A', a);
    return a
  }

HTML:

<div *ngFor="let row of hexRows | keyvalue:orderByRowNum">
  {{row.key}}
</div>

这可能是一个可怕的实现,我不确定100%为什么会起作用,但我要发布它,因为至少看起来像是进步。

1 个答案:

答案 0 :(得分:0)

表面上看来localeCompare会有所帮助,但对我而言却无济于事,所以我不会仅仅依靠它。

您需要应用自然排序算法对键进行排序。

尝试一下。我从这里https://snipplr.com/view/36012/javascript-natural-sort/提取了javascript中的自然排序算法,并对其进行了重构以更好地适应打字稿规则。此外,还会应用localeCompare代替本地字符串压缩器。

private orderByRowNum = (aKv: KeyValue<string, any>, bKv: KeyValue<string, any>) => {

    const rx: RegExp = /(\d+)|(\D+)/g;
    const rd: RegExp = /\d+/;

    const as: string = aKv.key;
    const bs: string = bKv.key;

    const a: RegExpMatchArray = String(as).match(rx);
    const b: RegExpMatchArray = String(bs).match(rx);

    while (a.length && b.length) {
        const a1: string = a.shift();
        const b1: string = b.shift();
        if (rd.test(a1) || rd.test(b1)){
            if (!rd.test(a1)) {
                return 1;
            }
            if (!rd.test(b1)) {
                return -1;
            }
            if (a1 !== b1) {
                return Number(a1) - Number(b1);
            }
        } else {
            if (a1 !== b1) {
                return a1.localeCompare(b1);
            }
        }
    }
    return a.length - b.length;
}

最好将它带到一些util类中,以使其更可重用。