前言回顾
分页完成后,我们项目主要工作目前只剩下 comments
内容展示部分,其它的都是一些查询分类的工作,我们会在今明两天完成这个项目剩下的问题,一些业务逻辑的内容如果有兴趣的同学可以自行补充完善。
开始
评论
我们先来看一下 hacker news
基本的评论包含了哪些内容:
![709d96e7196804e79f4c3824bbd1bf72.png](https://img-blog.csdnimg.cn/img_convert/709d96e7196804e79f4c3824bbd1bf72.png)
从内容上看,至少包含几个属性:作者
、评论时间
、评论内容
、回复
,NG-ZORRO 也为我们提供了 Comment
组件来渲染评论信息。
Comment 组件
开始之前
先准备好评论页的组件 StoryDetailComponent
$ cd ng-zorro-ironman2020
$ ng g c components/demos/hacker-news/story-detail --skip-import
nz-comment
包含这几个部分:
nz-comment
:评论主体,支持nzAuthor
、nzDatetime
显示作者和创建时间信息nz-comment-avatar
:要显示为评论头像的元素(如果有的话)nz-comment-content
:评论的主要内容nz-comment-action
:在评论内容下面呈现的操作项
非常完善的组件,基本能够涵盖我们需要的一切,我们尝试拿 nz-comment
渲染 API 返回的单条评论数据看一下:在线示例。
嵌套评论
但是我们不仅需要显示单条评论,还需要显示该评论下的回复评论,实现遍历渲染。我们可以使用 Angilar NgTemplateOutlet
指令来实现内嵌视图,ngTemplateOutletContext
则允许我们为 EmbeddedViewRef
附加一个上下文对象,这样我们就可以在模板里使用这个对象。
Tips:在上下文对象中使用 $implicit 这个 key 会把对应的值设置为默认值。
看一下官方的例子是怎么使用的:
@Component({
selector: 'ng-template-outlet-example',
template: `
<ng-container *ngTemplateOutlet="greet"></ng-container>
<ng-container *ngTemplateOutlet="eng; context: myContext"></ng-container>
<ng-container *ngTemplateOutlet="svk; context: myContext"></ng-container>
<ng-template #greet><span>Hello</span></ng-template>
-> name is $implicit
<ng-template #eng let-name><span>Hello {{name}}! </span></ng-template>
-> person is localSk
<ng-template #svk let-person="localSk"><span>Ahoj {{person}}! </span></ng-template>
`
})
export class NgTemplateOutletExample {
myContext = {$implicit: 'World', localSk: 'Svet'};
}
渲染数据
我们用同样的方法来显示评论内容,看一下我们是如何操作的:
<!--comment body-->
<ng-template #commentTemplateRef let-comment="comment">
<nz-comment [nzAuthor]="comment.author" nzDatetime="{{comment.created_at | timeAgo}}">
<nz-avatar nz-comment-avatar nzIcon="user" [nzSrc]="comment?.avatar || 'https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png'"></nz-avatar>
<nz-comment-content>
<p [innerHTML]="comment.text"></p>
</nz-comment-content>
<nz-comment-action>Reply to</nz-comment-action>
<!--注意这一行,如果存在评论回复,遍历复用渲染-->
<ng-container *ngIf="comment.children && comment.children.length">
<ng-template ngFor let-child [ngForOf]="comment.children">
<ng-template [ngTemplateOutlet]="commentTemplateRef" [ngTemplateOutletContext]="{ comment: child }">
</ng-template>
</ng-template>
</ng-container>
</nz-comment>
</ng-template>
<!--comment list loop-->
<ng-container *ngFor="let item of listOfComments">
<ng-template [ngTemplateOutlet]="commentTemplateRef" [ngTemplateOutletContext]="{ comment: item }"> </ng-template>
</ng-container>
因为 children
属性是完全一致的数据结构,所以我们可以直接复用设计的 nz-comment
结构。StoryDetailComponent
中直接请求详情接口即可:
export class StoryDetailComponent implements OnInit {
@Input() storyId: string;
loading = true;
listOfComments: IReplyComment[];
getStory() {
this.loading = true;
this.hackerNewsService.getStoryByAlgolia(this.storyId).subscribe(data => {
this.listOfComments = data.children || [];
this.loading = false;
this.cdr.markForCheck();
});
}
constructor(
private hackerNewsService: HackerNewsService,
private cdr: ChangeDetectorRef
) {}
ngOnInit() {
this.getStory();
}
}
![c790bd95878c6f8ce5cede6d0c183246.png](https://img-blog.csdnimg.cn/img_convert/c790bd95878c6f8ce5cede6d0c183246.png)
加个 Skeleton 占位屏
对于一些 comments
数据较多的接口,请求返回会稍慢一些,我们使用 nz-skeleton
来显示等待页面(更多骨架屏内容可查看 官方文档 ):
<nz-skeleton [nzLoading]="loading" [nzActive]="true"></nz-skeleton>
查看内容
设计评论页面已经完成,我们结合之前的知识,使用 Drawer
抽屉组件来显示评论详情,我们修改一下 hacker-news.component.ts
:
showDetail(story: Hit) {
this.nzDrawerService.create({
nzTitle : story.title,
nzContent : StoryDetailComponent,
nzWidth : '100%',
nzPlacement : 'right',
nzContentParams: {
storyId: story.objectID
}
});
这样我们已经可以通过点击 comments
功能查看该新闻下的评论了,看一下我们最终的成果:
![a421cb45315123572710aaa801d52095.gif](https://img-blog.csdnimg.cn/img_convert/a421cb45315123572710aaa801d52095.gif)
总结 & 预告
今天主要介绍了一个不算太常用的组件 Comment
,对于博客类或新闻信息类项目比较有用,但是对于中后台项目中运用得倒是不算频繁,穿插介绍了一个与 Spin 组件
类似的组件 Skeleton骨架屏
,两者都主要用于加载等待过渡,给用户良好的交互体验,大家可以按需选择。
相关资料
- iThelp 文章地址:
![6b1101e49368547478ca69e5391aad8a.png](https://img-blog.csdnimg.cn/img_convert/6b1101e49368547478ca69e5391aad8a.png)
- Github 今日代码分支:
![7aa3c6fecf48f8f599979c2ddaa0660b.png](https://img-blog.csdnimg.cn/img_convert/7aa3c6fecf48f8f599979c2ddaa0660b.png)
- Skeleton:
- Comment: