這篇文章給大家分享的是有關(guān)Angular如何實(shí)現(xiàn)類似博客評論的遞歸顯示的內(nèi)容。小編覺得挺實(shí)用的,因此分享給大家做個(gè)參考,一起跟隨小編過來看看吧。
創(chuàng)新互聯(lián)公司是一家集成都網(wǎng)站設(shè)計(jì)、成都做網(wǎng)站、外貿(mào)網(wǎng)站建設(shè)、網(wǎng)站頁面設(shè)計(jì)、網(wǎng)站優(yōu)化SEO優(yōu)化為一體的專業(yè)網(wǎng)站制作公司,已為成都等多地近百家企業(yè)提供網(wǎng)站建設(shè)服務(wù)。追求良好的瀏覽體驗(yàn),以探求精品塑造與理念升華,設(shè)計(jì)最適合用戶的網(wǎng)站頁面。 合作只是第一步,服務(wù)才是根本,我們始終堅(jiān)持講誠信,負(fù)責(zé)任的原則,為您進(jìn)行細(xì)心、貼心、認(rèn)真的服務(wù),與眾多客戶在蓬勃發(fā)展的市場環(huán)境中,互促共生。
思路
我們在寫后臺(tái)程序的時(shí)候,經(jīng)常會(huì)遇到生成類似樹的這種數(shù)據(jù)結(jié)構(gòu),我們直覺就是使用遞歸的方法來實(shí)現(xiàn),起初我也是這么想的,就是寫一個(gè) Angular4 的遞歸方法,組成一個(gè)字符串,然后在界面顯示,類似下面代碼
@Component({ selector: "comment", template: '{{ comments }}' }) export class CommentComponent { public comments: string = ""; generateComment(Comment comment) { this.comments = this.comments + "<div>" + comment.content + "</div>"; if (comment.pComment != null) { generateComment(comment.pComment); } } }
很天真的以為可以了,結(jié)果一試,標(biāo)簽不會(huì)被解析,才想起已經(jīng)過了解析標(biāo)簽的過程了。。。
后來想著,現(xiàn)在的前端框架都是以組件化自稱, Angular4 也不例外,那么一個(gè) Component 可以嵌入任何 Component,那肯定可以嵌入自己,也就有了類似遞歸的概念了,想到這立馬試試。。。
具體實(shí)現(xiàn)
思路是這樣子,我定義了數(shù)據(jù)的格式,是每個(gè)評論下面有一個(gè)子評論數(shù)組,而不是每個(gè)評論有一個(gè)父評論,數(shù)據(jù)格式如下:
"comments": [ { "id": 1, "username": "James1", "time": "2017-07-09 21:02:21", "content": "哈哈哈1<h2>哈哈哈</h2>", "status": 1, "email": "1xxxx@xx.com", "cComments": [ { "id": 2, "username": "James2", "time": "2017-07-09 21:02:22", "content": "哈哈哈2", "status": 1, "email": "2xxxx@xx.com", "cComments": null } ] } ]
CommentComponent 組件實(shí)現(xiàn)了評論模塊,但是遞歸評論并不在這個(gè)組件實(shí)現(xiàn),而是在子組件 CommentViewComponent 實(shí)現(xiàn),因?yàn)?CommentComponent 還包括一個(gè)一個(gè)輸入評論的文本框。
評論總模塊 ComponentComponent 代碼:
comment.component.ts
@Component({ selector: 'comment', templateUrl: './comment.component.html', styleUrls: ['./comment.component.css'] }) export class CommentComponent implements OnInit { @Input() public comments: Comment[]; ngOnInit(): void { } }
comment.component.html
<div class="container font-small"> <div class="row"> <div class="col-lg-8 offset-lg-2 col-md-10 offset-md-1"> <comment-view [comments]="comments"></comment-view> <div class="well" id="comment"> <h5>{{ 'comment.leaveComment' | translate }}</h5> <form role="form"> <div class="form-group"> <input type="hidden" [(ngModel)]="id" name="id"> <textarea [(ngModel)]="content" name="content" class="form-control" rows="5"></textarea> </div> <button type="submit" class="btn btn-primary">Submit</button> </form> </div> </div> </div> </div>
comment.component.css
.media { font-size: 14px; } .media-object { padding-left: 10px; }
子模塊 ComponentViewComponent 代碼:
component-view.component.ts
@Component({ selector: 'comment-view', templateUrl: './comment-view.component.html', styleUrls: ['./comment-view.component.css'] }) export class CommentViewComponent implements OnInit { @Input() public comments: Comment[]; constructor(private router: Router, private activateRoute: ActivatedRoute ) { } ngOnInit(): void { } }
component-view.component.html
<div *ngFor="let comment of comments"> <div class="media"> <div class="pull-left"> <span class="media-object"></span> </div> <div class="media-body"> <h5 class="media-heading">{{ comment.username }} <small class="pull-right">{{ comment.time }} | <a href="#" rel="external nofollow" >{{ 'comment.reply' | translate }}</a></small> </h5> {{ comment.content }} <hr> <comment-view *ngIf="comment.cComments != null" [comments]="comment.cComments"></comment-view> </div> </div> </div>
comonent-view.component.css
.media { font-size: 14px; } .media-object { padding-left: 10px; }
結(jié)果
這時(shí)的展示結(jié)果如下圖所示:
上面只是說明了如何實(shí)現(xiàn)評論梯形顯示,在博客評論中我們經(jīng)??吹娇梢曰貜?fù)某一條評論,本文講述如何實(shí)現(xiàn)點(diǎn)擊某一條評論的回復(fù)按鈕后,獲取該條評論的內(nèi)容并顯示在輸入框中。類似 CSDN 博客評論一樣,點(diǎn)擊回復(fù)后輸入框自動(dòng)添加了 [reply]u011642663[/reply]
思路
依據(jù)上一篇文章中的評論梯形顯示,我們還需要實(shí)現(xiàn)點(diǎn)擊回復(fù)后,屏幕自動(dòng)到達(dá)輸入框位置,并且獲取了點(diǎn)擊回復(fù)的評論的信息。首先分解一下這個(gè)功能點(diǎn),在項(xiàng)目中我們也會(huì)經(jīng)常分解功能點(diǎn),這個(gè)功能點(diǎn)有 2 個(gè)小點(diǎn):一是在每條評論中加上 [回復(fù)] 按鈕,點(diǎn)擊回復(fù)后跳到輸入框位置;二是點(diǎn)擊回復(fù)后,獲取到點(diǎn)擊回復(fù)的那條評論的信息。下面我們一一解決。
跳轉(zhuǎn)到輸入框
我們接觸前段第一個(gè)語言便是 HTML,我們知道 HTML 中有一個(gè) # 定位,下面代碼簡單解釋一下。
假設(shè)這個(gè) HTML 代碼文件是 index.html
<html> <head> </head> <body> <a href="index.html#pointer" rel="external nofollow" >Click me to pointer</a> <div id="pointer"> <h2>哈哈哈哈</h2> </div> </body> </html>
上面代碼只要點(diǎn)擊 Click me to pointer 這個(gè)鏈接,頁面就會(huì)跳到 id=”pointer” 這個(gè) div 的位置。所以我們在實(shí)現(xiàn)這個(gè)點(diǎn)擊回復(fù)跳轉(zhuǎn)到輸入框中就可以使用這個(gè)方法。
我們在 comment-component.html 中將評論輸入框加入 id=”comment”,接下來就是路徑拼接的問題了,我們可以通過 Angular 的 Router 的 url 來獲取本頁面的路徑,然后在這個(gè)路徑后面加入 #comment 就可以實(shí)現(xiàn)跳轉(zhuǎn)了,下面是實(shí)現(xiàn)這個(gè)跳轉(zhuǎn)功能的代碼
添加 id=”comment”
comment-component.html
<!-- Comment --> <div class="container font-small"> <div class="row"> <div class="col-lg-8 offset-lg-2 col-md-10 offset-md-1"> <comment-view [comments]="comments" (contentEvent)="getReplyComment($event)" ></comment-view> <div class="well" id="comment"> <h5>{{ 'comment.leaveComment' | translate }}</h5> <form role="form"> <div class="form-group"> <input type="hidden" [(ngModel)]="id" name="id"> <textarea [(ngModel)]="content" name="content" class="form-control" rows="5"></textarea> </div> <button type="submit" class="btn btn-primary">Submit</button> </form> </div> </div> </div> </div>
添加通過路由獲取當(dāng)前頁面 URL
comment-view.component.ts
@Component({ selector: 'comment-view', templateUrl: './comment-view.component.html', styleUrls: ['./comment-view.component.css'] }) export class CommentViewComponent implements OnInit { @Input() public comments: Comment[]; // 用于跳轉(zhuǎn)到回復(fù)輸入框的url拼接 public url: string = ""; constructor(private router: Router, private activateRoute: ActivatedRoute ) { } ngOnInit(): void { this.url = this.router.url; this.url = this.url.split("#")[0]; this.url = this.url + "#comment"; } }
添加鏈接 href=”“
comment-view.component.html
<div *ngFor="let comment of comments"> <div class="media"> <div class="pull-left"> <span class="media-object"></span> </div> <div class="media-body"> <h5 class="media-heading">{{ comment.username }} <small class="pull-right">{{ comment.time }} | <a href="{{url}}" rel="external nofollow" rel="external nofollow" (click)="reply(comment)" >{{ 'comment.reply' | translate }}</a></small> </h5> {{ comment.content }} <hr> <comment-view *ngIf="comment.cComments != null" [comments]="comment.cComments" (contentEvent)="transferToParent($event)"></comment-view> </div> </div> </div>
這就實(shí)現(xiàn)了頁面跳轉(zhuǎn)的功能點(diǎn),接下來實(shí)現(xiàn)獲取回復(fù)的評論的信息。
獲取回復(fù)的評論信息
有人會(huì)說獲取回復(fù)的評論信息,這不簡單么?加個(gè) click 事件不就行了。還記得上一篇文章咱們是如何實(shí)現(xiàn)梯形展示評論的么?咱們是通過遞歸來實(shí)現(xiàn)的,怎么添加 click 事件讓一個(gè)不知道嵌了多少層的組件能夠把評論信息傳給父組件?首先不具體想怎么實(shí)現(xiàn),我們這個(gè)思路是不是對的:把子組件的信息傳給父組件?答案是肯定的,我們就是要把不管嵌了多少層的子組件的信息傳給 comment.component.ts 這個(gè)評論模塊的主組件。
Angular 提供了 @Output 來實(shí)現(xiàn)子組件向父組件傳遞信息,我們在 comment-view.component.ts 模塊中添加 @Output 向每個(gè)調(diào)用它的父組件傳信息,我們是嵌套的,這樣一層一層傳出來,直到傳給 comment-component.ts 組件。我們看代碼怎么實(shí)現(xiàn)。
實(shí)現(xiàn)代碼
comment-view.component.ts
@Component({ selector: 'comment-view', templateUrl: './comment-view.component.html', styleUrls: ['./comment-view.component.css'] }) export class CommentViewComponent implements OnInit { @Input() public comments: Comment[]; // 點(diǎn)擊回復(fù)時(shí)返回?cái)?shù)據(jù) @Output() public contentEvent: EventEmitter<Comment> = new EventEmitter<Comment>(); // 用于跳轉(zhuǎn)到回復(fù)輸入框的url拼接 public url: string = ""; constructor(private router: Router, private activateRoute: ActivatedRoute ) { } ngOnInit(): void { this.url = this.router.url; this.url = this.url.split("#")[0]; this.url = this.url + "#comment"; } reply(comment: Comment) { this.contentEvent.emit(comment); } transferToParent(event) { this.contentEvent.emit(event); } }
comment-view.component.html
<div *ngFor="let comment of comments"> <div class="media"> <div class="pull-left"> <span class="media-object"></span> </div> <div class="media-body"> <h5 class="media-heading">{{ comment.username }} <small class="pull-right">{{ comment.time }} | <a href="{{url}}" rel="external nofollow" rel="external nofollow" (click)="reply(comment)" >{{ 'comment.reply' | translate }}</a></small> </h5> {{ comment.content }} <hr> <comment-view *ngIf="comment.cComments != null" [comments]="comment.cComments" (contentEvent)="transferToParent($event)"></comment-view> </div> </div> </div>
comment.component.ts
@Component({ selector: 'comment', templateUrl: './comment.component.html', styleUrls: ['./comment.component.css'] }) export class CommentComponent implements OnInit { @Input() public comments: Comment[]; // 要回復(fù)的評論 public replyComment: Comment = new Comment(); public id: number = 0; public content: string = ""; ngOnInit(): void { } getReplyComment(event) { this.replyComment = event; this.id = this.replyComment.id; this.content = "[reply]" + this.replyComment.username + "[reply]\n"; } }
comment.component.html
<!-- Comment --> <div class="container font-small"> <div class="row"> <div class="col-lg-8 offset-lg-2 col-md-10 offset-md-1"> <comment-view [comments]="comments" (contentEvent)="getReplyComment($event)" ></comment-view> <div class="well" id="comment"> <h5>{{ 'comment.leaveComment' | translate }}</h5> <form role="form"> <div class="form-group"> <input type="hidden" [(ngModel)]="id" name="id"> <textarea [(ngModel)]="content" name="content" class="form-control" rows="5"></textarea> </div> <button type="submit" class="btn btn-primary">Submit</button> </form> </div> </div> </div> </div>
解釋一下代碼邏輯:
我們在 comment-view.component.ts 添加以下幾點(diǎn):
定義了@Output() contentEvent
添加了reply(comment: Comment) 事件在點(diǎn)擊回復(fù)的時(shí)候觸發(fā)的,觸發(fā)的時(shí)候 contentEvent 將 comment 傳到父模塊
添加 transferToParent(event) 是接受子組件傳來的 event, 并且繼續(xù)將 event 傳到父組件
在 comment.component.ts 中定義了 getReplyComment(event) 方法,該方法接收子組件傳遞來的評論信息,并將信息顯示在頁面上。大功告成。。。
效果圖
感謝各位的閱讀!關(guān)于“Angular如何實(shí)現(xiàn)類似博客評論的遞歸顯示”這篇文章就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,讓大家可以學(xué)到更多知識(shí),如果覺得文章不錯(cuò),可以把它分享出去讓更多的人看到吧!
網(wǎng)站標(biāo)題:Angular如何實(shí)現(xiàn)類似博客評論的遞歸顯示
本文來源:http://www.rwnh.cn/article26/gposcg.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供外貿(mào)建站、App設(shè)計(jì)、標(biāo)簽優(yōu)化、移動(dòng)網(wǎng)站建設(shè)、網(wǎng)站維護(hù)、響應(yīng)式網(wǎng)站
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)