欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Angular實(shí)現(xiàn)類似博客評(píng)論的遞歸顯示及獲取回復(fù)評(píng)論的數(shù)據(jù)

 更新時(shí)間:2017年11月06日 11:18:47   作者:1CSH1  
這篇文章主要給大家介紹了關(guān)于Angular如何實(shí)現(xiàn)類似博客評(píng)論的遞歸顯示及獲取回復(fù)評(píng)論的數(shù)據(jù)的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧。

前言

我們?cè)谝恍┘夹g(shù)博客中會(huì)經(jīng)??吹胶芏噙f歸評(píng)論,也即是我們可以回復(fù)博友的評(píng)論,且界面很美觀,有梯度的顯示格式,日前在空余時(shí)間寫(xiě)類似的 demo,所以記錄下來(lái),可以給需要的人一些借鑒的作用。
好了,廢話少說(shuō),直奔主題。。。

思路

我們?cè)趯?xiě)后臺(tái)程序的時(shí)候,經(jīng)常會(huì)遇到生成類似樹(shù)的這種數(shù)據(jù)結(jié)構(gòu),我們直覺(jué)就是使用遞歸的方法來(lái)實(shí)現(xiàn),起初我也是這么想的,就是寫(xiě)一個(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)過(guò)了解析標(biāo)簽的過(guò)程了。。。

后來(lái)想著,現(xiàn)在的前端框架都是以組件化自稱, Angular4 也不例外,那么一個(gè) Component 可以嵌入任何 Component,那肯定可以嵌入自己,也就有了類似遞歸的概念了,想到這立馬試試。。。

具體實(shí)現(xiàn)

思路是這樣子,我定義了數(shù)據(jù)的格式,是每個(gè)評(píng)論下面有一個(gè)子評(píng)論數(shù)組,而不是每個(gè)評(píng)論有一個(gè)父評(píng)論,數(shù)據(jù)格式如下:

"comments": 
  [
  {
   "id": 1,
   "username": "James1",
   "time": "2017-07-09 21:02:21",
   "content": "哈哈哈1<h1>哈哈哈</h1>",
   "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)了評(píng)論模塊,但是遞歸評(píng)論并不在這個(gè)組件實(shí)現(xiàn),而是在子組件 CommentViewComponent 實(shí)現(xiàn),因?yàn)?CommentComponent 還包括一個(gè)一個(gè)輸入評(píng)論的文本框。

評(píng)論總模塊 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">
  <h4>{{ 'comment.leaveComment' | translate }}</h4>
  <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">
  <h4 class="media-heading">{{ comment.username }}
  <small class="pull-right">{{ comment.time }}&nbsp;|&nbsp;<a href="#" rel="external nofollow" >{{ 'comment.reply' | translate }}</a></small>
  </h4>
  {{ 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é)果如下圖所示:

上面只是說(shuō)明了如何實(shí)現(xiàn)評(píng)論梯形顯示,在博客評(píng)論中我們經(jīng)??吹娇梢曰貜?fù)某一條評(píng)論,本文講述如何實(shí)現(xiàn)點(diǎn)擊某一條評(píng)論的回復(fù)按鈕后,獲取該條評(píng)論的內(nèi)容并顯示在輸入框中。類似 CSDN 博客評(píng)論一樣,點(diǎn)擊回復(fù)后輸入框自動(dòng)添加了 [reply]u011642663[/reply]

思路

依據(jù)上一篇文章中的評(píng)論梯形顯示,我們還需要實(shí)現(xiàn)點(diǎn)擊回復(fù)后,屏幕自動(dòng)到達(dá)輸入框位置,并且獲取了點(diǎn)擊回復(fù)的評(píng)論的信息。首先分解一下這個(gè)功能點(diǎn),在項(xiàng)目中我們也會(huì)經(jīng)常分解功能點(diǎn),這個(gè)功能點(diǎn)有 2 個(gè)小點(diǎn):一是在每條評(píng)論中加上 [回復(fù)] 按鈕,點(diǎn)擊回復(fù)后跳到輸入框位置;二是點(diǎn)擊回復(fù)后,獲取到點(diǎn)擊回復(fù)的那條評(píng)論的信息。下面我們一一解決。

跳轉(zhuǎn)到輸入框

我們接觸前段第一個(gè)語(yǔ)言便是 HTML,我們知道 HTML 中有一個(gè) # 定位,下面代碼簡(jiǎn)單解釋一下。

假設(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">
  <h1>哈哈哈哈</h1>
 </div>
 </body>
</html>

上面代碼只要點(diǎn)擊 Click me to pointer 這個(gè)鏈接,頁(yè)面就會(huì)跳到 id=”pointer” 這個(gè) div 的位置。所以我們?cè)趯?shí)現(xiàn)這個(gè)點(diǎn)擊回復(fù)跳轉(zhuǎn)到輸入框中就可以使用這個(gè)方法。

我們?cè)?comment-component.html 中將評(píng)論輸入框加入 id=”comment”,接下來(lái)就是路徑拼接的問(wèn)題了,我們可以通過(guò) Angular 的 Router 的 url 來(lái)獲取本頁(yè)面的路徑,然后在這個(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">
  <h4>{{ 'comment.leaveComment' | translate }}</h4>
  <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>

添加通過(guò)路由獲取當(dāng)前頁(yè)面 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">
  <h4 class="media-heading">{{ comment.username }}
  <small class="pull-right">{{ comment.time }}&nbsp;|&nbsp;<a href="{{url}}" rel="external nofollow" rel="external nofollow" (click)="reply(comment)" >{{ 'comment.reply' | translate }}</a></small>
  </h4>
  {{ comment.content }}
  <hr>
  <comment-view *ngIf="comment.cComments != null" [comments]="comment.cComments" (contentEvent)="transferToParent($event)"></comment-view>
 </div>
 </div>
</div>

這就實(shí)現(xiàn)了頁(yè)面跳轉(zhuǎn)的功能點(diǎn),接下來(lái)實(shí)現(xiàn)獲取回復(fù)的評(píng)論的信息。

獲取回復(fù)的評(píng)論信息

有人會(huì)說(shuō)獲取回復(fù)的評(píng)論信息,這不簡(jiǎn)單么?加個(gè) click 事件不就行了。還記得上一篇文章咱們是如何實(shí)現(xiàn)梯形展示評(píng)論的么?咱們是通過(guò)遞歸來(lái)實(shí)現(xiàn)的,怎么添加 click 事件讓一個(gè)不知道嵌了多少層的組件能夠把評(píng)論信息傳給父組件?首先不具體想怎么實(shí)現(xiàn),我們這個(gè)思路是不是對(duì)的:把子組件的信息傳給父組件?答案是肯定的,我們就是要把不管嵌了多少層的子組件的信息傳給 comment.component.ts 這個(gè)評(píng)論模塊的主組件。
Angular 提供了 @Output 來(lái)實(shí)現(xiàn)子組件向父組件傳遞信息,我們?cè)?comment-view.component.ts 模塊中添加 @Output 向每個(gè)調(diào)用它的父組件傳信息,我們是嵌套的,這樣一層一層傳出來(lái),直到傳給 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">
  <h4 class="media-heading">{{ comment.username }}
  <small class="pull-right">{{ comment.time }}&nbsp;|&nbsp;<a href="{{url}}" rel="external nofollow" rel="external nofollow" (click)="reply(comment)" >{{ 'comment.reply' | translate }}</a></small>
  </h4>
  {{ 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ù)的評(píng)論
 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">
  <h4>{{ 'comment.leaveComment' | translate }}</h4>
  <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>

解釋一下代碼邏輯:

我們?cè)?comment-view.component.ts 添加以下幾點(diǎn):

  • 定義了@Output() contentEvent
  • 添加了reply(comment: Comment) 事件在點(diǎn)擊回復(fù)的時(shí)候觸發(fā)的,觸發(fā)的時(shí)候 contentEvent 將 comment 傳到父模塊
  • 添加 transferToParent(event) 是接受子組件傳來(lái)的 event, 并且繼續(xù)將 event 傳到父組件

在 comment.component.ts 中定義了 getReplyComment(event) 方法,該方法接收子組件傳遞來(lái)的評(píng)論信息,并將信息顯示在頁(yè)面上。大功告成。。。

效果圖

總結(jié)

以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,如果有疑問(wèn)大家可以留言交流,謝謝大家對(duì)腳本之家的支持。

相關(guān)文章

  • Angular4.0中引入laydate.js日期插件的方法教程

    Angular4.0中引入laydate.js日期插件的方法教程

    在AngularJs中我們會(huì)不可避免的使用第三方庫(kù),例如jquery插件庫(kù)。下面這篇文章主要給大家介紹了關(guān)于Angular4.0中引入laydate.js日期插件的相關(guān)資料,需要的朋友可以參考借鑒,下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧。
    2017-12-12
  • angularJS+requireJS實(shí)現(xiàn)controller及directive的按需加載示例

    angularJS+requireJS實(shí)現(xiàn)controller及directive的按需加載示例

    本篇文章主要介紹了angularJS+requireJS實(shí)現(xiàn)controller及directive的按需加載示例,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-02-02
  • AngularJS基礎(chǔ) ng-open 指令簡(jiǎn)單實(shí)例

    AngularJS基礎(chǔ) ng-open 指令簡(jiǎn)單實(shí)例

    本文主要介紹AngularJS ng-open 指令,這里幫大家整理了ng-open指令的基本資料,有需要的小伙伴可以參考下
    2016-08-08
  • 基于datepicker定義自己的angular時(shí)間組件的示例

    基于datepicker定義自己的angular時(shí)間組件的示例

    這篇文章主要介紹了基于datepicker定義自己的angular時(shí)間組件,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-03-03
  • 深入淺出講解Angular變更檢測(cè)

    深入淺出講解Angular變更檢測(cè)

    這篇文章主要給大家介紹了關(guān)于Angular變更檢測(cè)的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2022-03-03
  • AngularJS自定義表單驗(yàn)證功能實(shí)例詳解

    AngularJS自定義表單驗(yàn)證功能實(shí)例詳解

    這篇文章主要介紹了AngularJS自定義表單驗(yàn)證功能,結(jié)合完整實(shí)例形式詳細(xì)分析了AngularJS實(shí)現(xiàn)表單驗(yàn)證的相關(guān)指令、模型綁定、數(shù)據(jù)驗(yàn)證等操作技巧,需要的朋友可以參考下
    2018-08-08
  • Angular實(shí)現(xiàn)類似博客評(píng)論的遞歸顯示及獲取回復(fù)評(píng)論的數(shù)據(jù)

    Angular實(shí)現(xiàn)類似博客評(píng)論的遞歸顯示及獲取回復(fù)評(píng)論的數(shù)據(jù)

    這篇文章主要給大家介紹了關(guān)于Angular如何實(shí)現(xiàn)類似博客評(píng)論的遞歸顯示及獲取回復(fù)評(píng)論的數(shù)據(jù)的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧。
    2017-11-11
  • Angularjs單選框相關(guān)的示例代碼

    Angularjs單選框相關(guān)的示例代碼

    本篇文章主要介紹了Angularjs單選框相關(guān)的示例代碼,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-08-08
  • 在 Angular 中使用懶加載路由的方法

    在 Angular 中使用懶加載路由的方法

    延遲加載是一種限制加載用戶當(dāng)前需要的模塊的方法,這可以提高應(yīng)用程序的性能并減小初始捆綁包大小,在本文中,您學(xué)習(xí)了如何在 Angular 應(yīng)用程序中使用惰性加載路由,本文分步驟講解的非常詳細(xì),感興趣的朋友一起看看吧
    2024-02-02
  • 關(guān)于angularJs指令的Scope(作用域)介紹

    關(guān)于angularJs指令的Scope(作用域)介紹

    下面小編就為大家?guī)?lái)一篇angularJs指令的Scope(作用域)介紹。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2016-10-10

最新評(píng)論