Lakis
Lakis

Reputation: 299

*ngFor in Angular2

Ok I have a service bootstraped in boot.ts and everything is working fine apart from managing to make my template work. I apologize for not being able to express myself in HTML / angular lingo but I believe that my question is rather obvious.

My simplified *ngFor loop currently looks like this.

<div *ngFor="let comment of comments">
   <div>{{comment.body}}</div>
</div>

This as expected outputs something like the following

<div>
  <div> First comment </div><!-- 1st comment_div closed -->
  <div> Second comment </div><!-- 2nd comment_div closed -->
     .....
  <div> Last comment </div><!-- last comment_div closed
</div>

Instead what I want is the following

<div>
  <div> First comment 
    <div> Second comment 
     .....
       <div> Last comment </div>.....</div></div> <!-- All divs closing here-->
</div>

Upvotes: 0

Views: 2991

Answers (3)

Try something like this: inside Typescript:

@Component({
    selector: 'comment',
    template: "<comment [comment]="comment" *ngFor="let comment of comments"> </comment> <div> {{comment?.body}} </div>",
    directives: [CommentComponent]
})
export class CommentComponent {
      @Input() private comment : Comment;
      private comments : Array<Comment>;
}

Comment class

export class Comment {
    public comments : Array<Comment>;
}

The idea is use angular template generation to generate your tree until there's no more levels.

Upvotes: 1

Lakis
Lakis

Reputation: 299

OK. So by tinkering with the previous answers I managed to get it done although obviously it wastes CPU cycles and I have no idea if it creates issues with data that might not be static.

1st) ngFor should be much more similar to a classic for loop : for(var i=0; i

Anyways

comment.ts

import { Component, OnInit, Input} from '@angular/core';
import {MyService} from 'somewhere';
import {MessagePost} from 'somewhere else';

@Component({
moduleId: module.id,
selector: 'comment',
templateUrl: 'comment.html',
directives: [CommentComponent], //This is important!
})
export class CommentComponent implements OnInit {

@Input() subcomments: Array<MessagePost>;

@Input() iterator: number =0;

constructor(private _myService: MyService) { }

ngOnInit() {
    if(!subcomments){this.subcomments = this._myService.getMessage();}           
}

}



comment.html (template)

<div style="padding-left:40px;" *ngIf="subcomments && subcomments.length>0 && subcomments.length -1 >iterator">
  {{subcomments[iterator].body}}
  <comment [subcomments]="subcomments" [iterator]="iterator + 1">   </comment>
 </div>

Upvotes: 0

null canvas
null canvas

Reputation: 10603

Here is a working version, just pass your comments array to this directive:

https://plnkr.co/edit/SbLJ3eEHU4BKGOPiXioZ?p=preview

import {Component, Input, OnInit} from '@angular/core';
import {NgFor} from '@angular/common';

@Component({
  selector: 'my-comment',
  providers: [],
  template: `
    <div style="padding-left:20px;" *ngIf="subcomments && subcomments.length > 0">
     {{subcomments[0] }}    
     <my-comment [subcomments]="subcomments  ?  subcomments.slice(1): null"></my-comment>  
    </div>
  `,  
  directives: [NgFor, MyComment] 
})
export class MyComment implements OnInit {
  @Input() subcomments: Array<String>;

  ngOnInit(): void { 

    console.log( this.subcomments.slice(1));
  }
}

And this is how you use the my-comment directive:

//our root app component
import {Component} from '@angular/core';
import {NgFor} from '@angular/common';
import {MyComment} from 'src/myComment';

@Component({
  selector: 'my-app',
  providers: [],

  template: `
    <div>
      <h2 *ngFor="let i of items; let k =index">Hello {{name+k}}</h2>

        <my-comment [subcomments]="items"></my-comment>      
    </div>
  `,
  directives: [NgFor,MyComment]
})
export class App {
  items : [] = ['ha', 'da', 'fdd'];
  constructor() {
    this.name = 'Angular2 (Release Candidate!)'
  }
}

Upvotes: 1

Related Questions