我想创建一个按天排序的历史,就像一个在chrome:
铬历史
然而,我发现很难把所有的历史按天分类。
这是我目前得到的:
Vue历史
如您所见,我可以显示历史元素的创建日期,但我不能按创建日期对所有历史进行排序。
这是我到目前为止所做的:
我已经创建了一个json服务器,从中获取和操作我的数据:
{
"history": [
{
"id": 576791835,
"date": "2022-06-27T18:31:38.083Z",
},
{
"id": 911123993,
"date": "2022-06-27T18:31:46.972Z",
},
{
"id": 416865594,
"date": "2022-06-27T18:32:54.990Z",
},
{
"id": 520724162,
"date": "2022-06-27T18:33:35.822Z",
},
{
"id": 536654574,
"date": "2022-06-27T18:33:41.821Z",
},
]
}
我已经使用NgRx实现了一个存储,这是我的组件:
export class HistoryComponent implements OnInit{
Contents$:Observable<History[]>;
ContentsInOrder$:Observable<Content[]>;
Histories$=this.facade.Histories$;
Date= new Date;
showTrash = false;
onDeleteHistory(history:History){
this.facade.deleteHistory(history);
}
onAddHistory(content:Data){
const history : History ={
id : Math.floor(Math.random() * 999999999),
date : new Date(),
}
this.store.addHistory(histo);
@Output() click: EventEmitter<void> = new EventEmitter();
onclick(){
this.click.emit();
}
openDialog(){
this.dialog.open(DialogComponent);
}
}
这是我的组件模板:
<div mat-subheader *ngIf="(Histories$ | async).length===0">The documents you visit will show here</div>
<mat-list-item *ngFor="let history of Histories$ | async" class="historyClicking" (mouseover)="history.showTrash=true" (mouseout)="history.showTrash=false" (click)="onclick()">
<div class="block">
<div matList>{{history.id}}</div>
</div>
</mat-list-item>
</div>
</mat-tab>
</mat-tab-group>
</div>
</div>
</div>
下面是我的服务功能:
addHistory(history:History){
return this.http.post(this.apiURL, history);
}
deleteHistory(id:number){
return this.http.delete(this.apiURL+'/'+id)
}
感谢您的宝贵时间!
还好你用的是可观察对象。看起来你已经把History$
项按顺序排好了。因此,让我们再添加一个自定义管道,以便在模板中按天对项目进行分组。为此,我们使用<ng-container>
在更高的一层循环项。我们每天创造<div>
,在每一天我们放置<mat-list-item>
-你当然可以改变这个,但这是它的基本思想。
使用| datePipe
我们格式化日期history.date | date : 'EEEE, MMMM M, YYYY'
。https://angular.io/api/common/DatePipe。然后按天分组,我使用| slice
与之前的值进行比较(这样每个日标题将被渲染一次)。
<strong *ngIf="(history.date | date: 'EEEE, MMMM d, YYYY') != ((Histories$ | async)[i-1]?.date | date: 'EEEE, MMMM d, YYYY')">{{ history.date | date: 'EEEE, MMMM d, YYYY' }}</strong>```
I'm sure there better ways for this, like grouping the data by key/values where key is one day, but for not it works.
However if you want dates spelled e.g "Yesterday" you need to make a custom implementation for this or use some `humanizer` package.
```html
<ng-container *ngIf="Histories$ | async">
<ng-container *ngFor="let history of Histories$ | async; let i = index">
<strong
*ngIf="
(history.date | date: 'EEEE, MMMM d, YYYY') !=
((Histories$ | async)[i - 1]?.date | date: 'EEEE, MMMM d, YYYY')
"
>
<br />
<br />
{{ history.date | date: 'EEEE, MMMM d, YYYY' }}
<br />
</strong>
<br />
<div
*ngIf="
(history.date | date: 'YYYY-MM-dd') ==
(history.date | slice: 0:10).toString()
"
>
<mat-list-item
class="historyClicking"
(mouseover)="history.showTrash = true"
(mouseout)="history.showTrash = false"
(click)="onclick()"
>
<div class="block">
<div matList>{{ history.date }}</div>
<div matList>{{ history.SNS }}</div>
<div matList>{{ history.title }}</div>
<div matList>{{ history.DMC }}</div>
</div>
</mat-list-item>
</div>
</ng-container>
</ng-container>
工作示例:https://stackblitz.com/edit/kingsbury-angular-w-material-tpuwdy?file=src%2Fapp%2Fapp.component.html
仔细想想,上面的⬆️看起来很糟糕。
预先用自定义管道分离数据是一个更好的主意。因此,我创建了一个自定义管道,按天对项目进行分组,然后使用*ngFor
对组进行迭代,然后对组中的项目进行迭代:
@Pipe({ name: 'groupByDay' })
export class GroupByDayPipe implements PipeTransform {
transform(items: any[]): any[] {
// this gives an object with dates as keys
const groups = items.reduce((groups, game) => {
const date = game.date.split('T')[0];
if (!groups[date]) {
groups[date] = [];
}
groups[date].push(game);
return groups;
}, {});
// Edit: to add it in the array format instead
const groupArrays = Object.entries(groups);
console.log(groupArrays);
return groupArrays;
}
}
// [['2022-06-28', Array(1)],
// ['2022-06-27', Array(7)]]
<ng-container *ngIf="Histories$ | async">
<ng-container
*ngFor="let group of Histories$ | async | groupByDay"
>
<strong>{{ group[0] | date: 'EEEE, MMMM d, YYYY' }}</strong>
<br />
<br />
<div *ngFor="let history of group[1]">
<mat-list-item
class="historyClicking"
(mouseover)="history.showTrash = true"
(mouseout)="history.showTrash = false"
(click)="onclick()"
>
<div class="block">
<div matList>{{ history.date }}</div>
<div matList>{{ history.SNS }}</div>
<div matList>{{ history.title }}</div>
<div matList>{{ history.DMC }}</div>
</div>
</mat-list-item>
<br />
<br />
</div>
</ng-container>
</ng-container>
工作示例:https://stackblitz.com/edit/kingsbury-angular-w-material-p4h1vg?file=src%2Fapp%2Fapp.component.html
只是一些旁注。通常我们使用camelCase
来命名变量。