Maison  >  Article  >  interface Web  >  Exemple détaillé de la façon dont Angular implémente l'affichage récursif des commentaires de blog et obtient des données pour les commentaires de réponse

Exemple détaillé de la façon dont Angular implémente l'affichage récursif des commentaires de blog et obtient des données pour les commentaires de réponse

小云云
小云云original
2017-12-26 13:55:072322parcourir

Cet article vous présente principalement les informations pertinentes sur la façon dont Angular implémente un affichage récursif similaire aux commentaires de blog et obtient des données pour répondre aux commentaires. L'article les présente en détail à travers un exemple de code, qui a une certaine valeur d'apprentissage de référence pour l'étude ou le travail de chacun. ., amis qui en ont besoin, veuillez suivre l'éditeur pour apprendre ensemble.

Avant-propos

On voit souvent beaucoup de commentaires récursifs dans certains blogs techniques, c'est-à-dire qu'on peut répondre aux commentaires des blogueurs, et l'interface est très belle et a un format d'affichage dégradé. Récemment, j’écris des démos similaires pendant mon temps libre, donc les enregistrer peut fournir une référence à ceux qui en ont besoin.
Bon, assez de bêtises, allons droit au but. . .

Idée

Lorsque nous écrivons des programmes en arrière-plan, nous rencontrons souvent des structures de données similaires à des arbres. Notre intuition est d'utiliser des méthodes récursives pour y parvenir. Au début, je le pensais aussi. , écrivez une méthode récursive dans Angular4 pour former une chaîne, puis affichez-la sur l'interface, similaire au code suivant

@Component({
 selector: "comment",
 template: '{{ comments }}'
})
export class CommentComponent {

 public comments: string = "";

 generateComment(Comment comment) {
 this.comments = this.comments + "<p>" + comment.content + "</p>";
 if (comment.pComment != null) {
  generateComment(comment.pComment);
 }
 }
}

Je pensais naïvement que c'était ok, mais quand je l'ai essayé, la balise ne pas être analysé, puis je me suis rappelé que nous avions suivi le processus d'analyse des balises. . .

Plus tard, j'y ai réfléchi, les frameworks front-end actuels prétendent tous être basés sur des composants, et Angular4 ne fait pas exception. Donc, si un composant peut être intégré dans n'importe quel composant, il peut certainement s'y intégrer, et là. est un concept similaire à la récursion. Pensez-y et essayez-le immédiatement. . .

L'implémentation spécifique

L'idée est la suivante. J'ai défini le format des données. Il y a un tableau de commentaires enfants sous chaque commentaire, au lieu que chaque commentaire ait un commentaire parent. le format des données est le suivant :

"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
   }
   ]
  }
  ]

Le composant CommentComponent implémente le module de commentaires, mais les commentaires récursifs ne sont pas implémentés dans ce composant, mais dans le sous-composant CommentViewComponent, car CommentComponent comprend également des zones de texte pour saisir des commentaires. par un.

Module total de commentaires ComponentComponent code :

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

<p class="container font-small">
 <p class="row">
 <p class="col-lg-8 offset-lg-2 col-md-10 offset-md-1">

  <comment-view [comments]="comments"></comment-view>

  <p class="well" id="comment">
  <h4>{{ 'comment.leaveComment' | translate }}</h4>
  <form role="form">
   <p class="form-group">
   <input type="hidden" [(ngModel)]="id" name="id">
   <textarea [(ngModel)]="content" name="content" class="form-control" rows="5"></textarea>
   </p>
   <button type="submit" class="btn btn-primary">Submit</button>
  </form>
  </p>
 </p>
 </p>
</p>

comment.component. css

.media {
 font-size: 14px;
}

.media-object {
 padding-left: 10px;
}

sous-module ComponentViewComponent code :

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

<p *ngFor="let comment of comments">
 <p class="media">
 <p class="pull-left">
  <span class="media-object"></span>
 </p>
 <p class="media-body">
  <h4 class="media-heading">{{ comment.username }}
  <small class="pull-right">{{ comment.time }} | <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>
 </p>
 </p>
</p>

comonent-view.component.css

.media {
 font-size: 14px;
}

.media-object {
 padding-left: 10px;
}

Résultat

Le résultat affiché à ce moment est le suivant :

Ce qui précède explique simplement comment réaliser l'affichage en échelle des commentaires. Dans les commentaires de blog, nous voyons souvent que vous pouvez répondre à un certain commentaire. Cet article décrit comment obtenir le contenu du commentaire et l'afficher dans la zone de saisie après avoir cliqué. le bouton de réponse d'un commentaire. Semblable aux commentaires du blog CSDN, après avoir cliqué sur répondre, la zone de saisie est automatiquement ajoutée [reply]u011642663[/reply]

Idée

Selon l'affichage en échelle des commentaires dans l'article précédent, nous reste à mettre en œuvre Après avoir cliqué pour répondre, l'écran atteint automatiquement la position de la zone de saisie et les informations du commentaire cliqué pour répondre sont obtenues. Tout d'abord, décomposons ce point de fonction. Dans le projet, nous décomposerons souvent le point de fonction. Ce point de fonction comporte deux petits points : Tout d'abord, ajoutez un bouton [répondre] à chaque commentaire, cliquez sur Répondre et passez à la zone de saisie. position; Deuxièmement, après avoir cliqué pour répondre, les informations du commentaire sur lequel on a cliqué pour répondre sont obtenues. Résolvons-les un par un ci-dessous.

Aller à la zone de saisie

Le premier langage avec lequel nous sommes entrés en contact dans la section précédente est HTML Nous savons qu'il existe un positionnement # en HTML. Le code suivant est brièvement expliqué.

Supposons que ce fichier de code HTML est index.html

<html>
 <head>
 </head>
 <body>
 <a href="index.html#pointer" rel="external nofollow" >Click me to pointer</a>
 <p id="pointer">
  <h1>哈哈哈哈</h1>
 </p>
 </body>
</html>

Tant que le code ci-dessus clique sur le lien Cliquez sur moi pour pointer, la page passera au p avec id="pointeur" emplacement. Nous pouvons donc utiliser cette méthode lors de l'implémentation de cette réponse au clic pour accéder à la zone de saisie.

Nous ajoutons id="comment" à la zone de saisie des commentaires dans comment-component.html L'étape suivante est le problème de l'épissage du chemin. Nous pouvons obtenir l'URL de cette page via l'URL de. Chemin du routeur Angular, puis ajoutez #comment après le chemin pour réaliser le saut. Voici le code pour implémenter cette fonction de saut

Ajouter id="comment"

comment-component. html

<!-- Comment -->
<p class="container font-small">
 <p class="row">
 <p class="col-lg-8 offset-lg-2 col-md-10 offset-md-1">

  <comment-view [comments]="comments" (contentEvent)="getReplyComment($event)" ></comment-view>

  <p class="well" id="comment">
  <h4>{{ 'comment.leaveComment' | translate }}</h4>
  <form role="form">
   <p class="form-group">
   <input type="hidden" [(ngModel)]="id" name="id">
   <textarea [(ngModel)]="content" name="content" class="form-control" rows="5"></textarea>
   </p>
   <button type="submit" class="btn btn-primary">Submit</button>
  </form>
  </p>
 </p>
 </p>
</p>

Ajouter pour obtenir l'URL de la page actuelle via le routage

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[];

 // 用于跳转到回复输入框的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";
 }
}

Ajouter un lien href=""

comment -view.component.html

<p *ngFor="let comment of comments">
 <p class="media">
 <p class="pull-left">
  <span class="media-object"></span>
 </p>
 <p class="media-body">
  <h4 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>
  </h4>
  {{ comment.content }}
  <hr>
  <comment-view *ngIf="comment.cComments != null" [comments]="comment.cComments" (contentEvent)="transferToParent($event)"></comment-view>
 </p>
 </p>
</p>

Cela réalise le point de fonction de saut de page, puis réalise l'obtention des informations du commentaire de réponse.

Obtenir des informations sur les commentaires en réponse

有人会说获取回复的评论信息,这不简单么?加个 click 事件不就行了。还记得上一篇文章咱们是如何实现梯形展示评论的么?咱们是通过递归来实现的,怎么添加 click 事件让一个不知道嵌了多少层的组件能够把评论信息传给父组件?首先不具体想怎么实现,我们这个思路是不是对的:把子组件的信息传给父组件?答案是肯定的,我们就是要把不管嵌了多少层的子组件的信息传给 comment.component.ts 这个评论模块的主组件。
Angular 提供了 @Output 来实现子组件向父组件传递信息,我们在 comment-view.component.ts 模块中添加 @Output 向每个调用它的父组件传信息,我们是嵌套的,这样一层一层传出来,直到传给 comment-component.ts 组件。我们看代码怎么实现。

实现代码

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[];
 // 点击回复时返回数据
 @Output()
 public contentEvent: EventEmitter<Comment> = new EventEmitter<Comment>();
 // 用于跳转到回复输入框的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

<p *ngFor="let comment of comments">
 <p class="media">
 <p class="pull-left">
  <span class="media-object"></span>
 </p>
 <p class="media-body">
  <h4 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>
  </h4>
  {{ comment.content }}
  <hr>
  <comment-view *ngIf="comment.cComments != null" [comments]="comment.cComments" (contentEvent)="transferToParent($event)"></comment-view>
 </p>
 </p>
</p>

comment.component.ts

@Component({
 selector: 'comment',
 templateUrl: './comment.component.html',
 styleUrls: ['./comment.component.css']
})
export class CommentComponent implements OnInit {

 @Input()
 public comments: Comment[];

 // 要回复的评论
 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 -->
<p class="container font-small">
 <p class="row">
 <p class="col-lg-8 offset-lg-2 col-md-10 offset-md-1">

  <comment-view [comments]="comments" (contentEvent)="getReplyComment($event)" ></comment-view>

  <p class="well" id="comment">
  <h4>{{ 'comment.leaveComment' | translate }}</h4>
  <form role="form">
   <p class="form-group">
   <input type="hidden" [(ngModel)]="id" name="id">
   <textarea [(ngModel)]="content" name="content" class="form-control" rows="5"></textarea>
   </p>
   <button type="submit" class="btn btn-primary">Submit</button>
  </form>
  </p>
 </p>
 </p>
</p>

解释一下代码逻辑:

我们在 comment-view.component.ts 添加以下几点:

  • 定义了@Output() contentEvent

  • 添加了reply(comment: Comment) 事件在点击回复的时候触发的,触发的时候 contentEvent 将 comment 传到父模块

  • 添加 transferToParent(event) 是接受子组件传来的 event, 并且继续将 event 传到父组件

在 comment.component.ts 中定义了 getReplyComment(event) 方法,该方法接收子组件传递来的评论信息,并将信息显示在页面上。大功告成。。。

效果图

相关推荐:

怎样用PHP开发博客评论系统!解决办法

博客评论回访者跟踪

如何PHP制作简易博客

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn