In diesem Artikel werden Ihnen hauptsächlich relevante Informationen darüber vorgestellt, wie Angular die rekursive Anzeige ähnlich wie bei Blog-Kommentaren implementiert und Daten zum Beantworten von Kommentaren erhält. Der Artikel führt sie ausführlich anhand von Beispielcode ein, der einen gewissen Referenz-Lernwert für jedermanns Studium oder Arbeit hat ., Freunde, die es brauchen, folgen Sie bitte dem Herausgeber, um gemeinsam zu lernen.
Vorwort
In einigen technischen Blogs sehen wir oft viele rekursive Kommentare, das heißt, wir können auf die Kommentare von Bloggern antworten, und die Benutzeroberfläche ist sehr schön und verfügt über ein Verlaufsanzeigeformat. Kürzlich schreibe ich in meiner Freizeit ähnliche Demos, sodass das Aufzeichnen dieser Demos als Referenz für diejenigen dienen kann, die sie benötigen.
Okay, genug Unsinn, kommen wir gleich zur Sache. . .
Idee
Wenn wir Hintergrundprogramme schreiben, stoßen wir oft auf baumähnliche Datenstrukturen. Das dachte ich mir zunächst auch , schreiben Sie eine rekursive Methode in Angular4, um eine Zeichenfolge zu bilden, und zeigen Sie sie dann auf der Schnittstelle an, ähnlich dem folgenden Code
@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); } } }
Ich dachte naiv, es sei in Ordnung, aber als ich es ausprobierte, war das Tag der Fall nicht analysiert werden, und dann fiel mir ein, dass wir den Prozess des Parsens von Tags durchlaufen haben. . .
Später habe ich darüber nachgedacht, dass die heutigen Front-End-Frameworks alle behaupten, komponentenbasiert zu sein, und Angular4 ist keine Ausnahme. Wenn also eine Komponente in eine beliebige Komponente eingebettet werden kann, kann sie sich definitiv selbst einbetten, und zwar dort ist ein Konzept, das der Rekursion ähnelt, und probieren Sie es sofort aus. . .
Die spezifische Implementierung
Die Idee ist, dass ich das Format der Daten unter jedem Kommentar definiert habe, anstatt dass jeder Kommentar einen übergeordneten Kommentar hat Das Datenformat lautet wie folgt:
"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 } ] } ]
Die Komponente „CommentComponent“ implementiert das Kommentarmodul, rekursive Kommentare werden jedoch nicht in dieser Komponente, sondern in der Unterkomponente „CommentViewComponent“ implementiert, da „CommentComponent“ auch Textfelder zur Eingabe von Kommentaren enthält um eins.
Comment total module 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; }
Submodul ComponentViewKomponentencode:
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; }
Ergebnis
Das Anzeigeergebnis zu diesem Zeitpunkt ist wie folgt:
Oben wird lediglich erklärt, wie die Leiteranzeige von Kommentaren realisiert wird. In Blog-Kommentaren sehen wir häufig, dass Sie auf einen bestimmten Kommentar antworten und ihn nach dem Klicken im Eingabefeld anzeigen können der Antwort-Button eines Kommentars. Ähnlich wie bei CSDN-Blog-Kommentaren fügt das Eingabefeld nach dem Klicken auf „Antworten“ automatisch „[Antwort]u011642663[/Antwort]“ hinzu
Idee
Gemäß der Leiteranzeige der Kommentare im vorherigen Artikel haben wir immer noch muss implementiert werden Nach dem Klicken zum Antworten erreicht der Bildschirm automatisch die Position des Eingabefelds und erhält die Informationen des Kommentars, auf den zum Antworten geklickt wurde. Lassen Sie uns zunächst diesen Funktionspunkt aufschlüsseln. Dieser Funktionspunkt hat häufig zwei kleine Punkte: Fügen Sie zunächst jedem Kommentar eine Schaltfläche [Antworten] hinzu, klicken Sie auf „Antworten“ und springen Sie zum Eingabefeld Position; Zweitens werden nach dem Klicken zum Antworten die Informationen des Kommentars abgerufen, auf den zum Antworten geklickt wurde. Lassen Sie uns sie unten einzeln lösen.
Springe zum Eingabefeld
Die erste Sprache, mit der wir im vorherigen Abschnitt in Berührung gekommen sind, ist HTML. Wir wissen, dass es in HTML eine #-Positionierung gibt.
Angenommen, diese HTML-Codedatei ist 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>
Solange der obige Code auf den Link „Zum Zeiger klicken“ klickt, springt die Seite zum p mit id="Zeiger"-Standort. Daher können wir diese Methode bei der Implementierung dieser Klickantwort verwenden, um zum Eingabefeld zu springen.
Wir fügen id="comment" zum Kommentareingabefeld in comment-component.html hinzu. Der nächste Schritt ist das Problem des Pfadspleißens. Wir können die URL dieser Seite über die URL abrufen Angulars Router. Fügen Sie dann #comment nach dem Pfad hinzu, um den Sprung zu implementieren.
Add 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>
Hinzufügen, um die aktuelle Seiten-URL durch Routing zu erhalten
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"; } }
Link hinzufügen 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>
Dies realisiert den Funktionspunkt des Seitensprungs und realisiert dann den Erhalt der Informationen des Antwortkommentars.
Informationen zu Antwortkommentaren erhalten
有人会说获取回复的评论信息,这不简单么?加个 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制作简易博客
Das obige ist der detaillierte Inhalt vonDetailliertes Beispiel dafür, wie Angular die rekursive Anzeige von Blog-Kommentaren implementiert und Daten für Antwortkommentare erhält. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!