如何在 Angular 中相互链接和路由两个 ngFor 循环?



我正在尝试使用角度构建一个网页。我只需要连接与第一个 ngFor 循环相关的第二个 ngFor 循环的数据。

网页代码

<div *ngFor="let year of years">
<h2> {{year}} </h2>   // For displaying the year row
</div>

<div *ngFor="let month of months">
<h4> {{month}}</h4> // For displaying the month row
</div>

//Now i need to print all the data respect to each month and data.
year = ['2019','2018','2017','2016']
month = ['jan','feb','mar','apr','may','jun','jul', 'aug','sep','oct','nov','dec']
Output should be like 

2019年 2018年 2017年2016

年1月 2月 3月 4月 6月 8月 8月 9月 10月 12月

(每个月和每年的所有数据都应如图所示(

2019

年8月8日 - 数据

8月5日 - 数据

6月28日 - 数据

1月5日 - 数据

2018

年12月29日 - 数据

12月21日 - 数据

18 10月 - 数据

(等等...

如果我们单击任何一年,页面将滚动到该年。 可能有该年的所有 12 个月数据,也可能只有几个月。 因此,假设如果我们单击2018,则页面将滚动到2018,然后"如果"我单击"10月",如果有2018年10月的数据,那么它将滚动到那里,否则什么都不会发生。它无法滚动到任何其他年份的 10 月。


The structure of data is like 
year -- date -- data
2019 -- 8th aug -- data
2019 -- 5th aug -- data

你可以像下面这样写第二个循环。

#1

<ng-container *ngFor="let names of name">
<div *ngIf="names.startsWith(selectedAlphabets)">
<h4> {{names}}</h4>
</div>
</ng-container>

尽管这不是好方法,因为每次更改 selectedAlphabets 时,它都必须再次迭代整个名称列表。 如果您可以将名称列表更改为字母字符映射到名称列表,那么它会更快,因为它可以直接选择所选字母表的列表,如下所示。

#2

import {
Component
} from '@angular/core';
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
alphaBet: string;
english = ['a', 'b', 'c', 'd', 'e', 'f'];
name = ['a1', 'a2', 'a3', 'a4',
'b1', 'b2', 'b3', 'b4',
'c1', 'c2', 'c3', 'c4',
'd1', 'd2', 'd3', 'd4',
'e1', 'e2', 'e3', 'e4',
'f1', 'f2', 'f3', 'f4'
];
nameMap = new Map<string, string[]>();
public ngOnInit(){
this.generateNameMap();
}
generateNameMap() {
for (const item of this.name) {
if (!this.nameMap.get(item.charAt(0))) {
this.nameMap.set(item.charAt(0), []);
}
this.nameMap.get(item.charAt(0)).push(item);
}
}

/* other code */
}

并像这样更改循环 HTML 部分的第二个

<div *ngFor="let names of nameMap.get(selectedAlphabets)">
<h4> {{names}}</h4>
</div>
<div *ngFor="let alphabets of english">
<h2 (click)=scrollToLetter(alphabets)> {{alphabets}} </h2>
</div>

<div *ngFor="let names of name">
<h4 id="{{names}}">{{names}}</h4>
</div>

然后在您的 TypeScript 中:

public scrollToLetter(letter) {
console.log(`scrolling to ${letter}`);
var id = this.name.find(function(element) {
return element.toLowerCase().startsWith(letter);
});
if (id) {
let el = document.getElementById(id);
el.scrollIntoView();
}
}

请记住对可滚动列表应用适当的样式,例如:

height: 50px;
max-height:50px;
overflow-y: scroll;

这是一种基于您在描述中提供的内容的方法。您只需要根据第一个列表的选定项目过滤第二个列表。堆栈闪电战演示

import {
Component
} from '@angular/core';
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
alphaBet: string;
english = ['a', 'b', 'c', 'd', 'e', 'f'];
name = ['a1', 'a2', 'a3', 'a4',
'b1', 'b2', 'b3', 'b4',
'c1', 'c2', 'c3', 'c4',
'd1', 'd2', 'd3', 'd4',
'e1', 'e2', 'e3', 'e4',
'f1', 'f2', 'f3', 'f4'
];
scrollToNames(val) {
const elems = [].slice.call(document.getElementsByClassName('names'));
const macthes = elems.filter((item) => {
return item.innerHTML.includes(val);
});
macthes[0].scrollIntoView();
}
}
<div *ngFor="let alphabets of english">
<h2 (click)="scrollToNames(alphabets)"> {{alphabets}} </h2>
</div>
<div *ngFor="let names of name">
<h4 class="names"> {{names}}</h4>
</div>

此外,还可以使用管道根据所选内容筛选第二个列表。这只是上面演示的一种方式;

希望这对:)有所帮助

最新更新