2

I'm trying to load an Angular 2 component recursively with a recursive array (plunk: http://plnkr.co/edit/3npsad?p=preview).

Given this recursive array:

[
  {
    "id": 1,
    "text": "abc"
  },
  {
    "id": 2,
    "text": "def",
    items: [
      {
        "id": 21,
        "text": "def-1",
        items: [
          {
            "id": 211,
            "text": "def-1-1"
          },
          {
            "id": 212,
            "text": "def-1-2"
          }
        ]
      },
      {
        "id": 22,
        "text": "def-2"
      }
    ]
  }
]

I need the following output:

<my-item>
    <div id="1" text="abc"></div>
</my-item>
<my-item>
    <div id="2" text="def"></div>
    <my-item>
        <div id="21" text="def-1"></div>
        <my-item>
            <div id="211" text="def-1-1"></div>
        </my-item>
        <my-item>
            <div id="212" text="def-1-2"></div>
        </my-item>
    </my-item>
    <my-item>
        <div id="22" text="def-2"></div>
    </my-item>
</my-item>

I could only render the first level of input as show in my plunk. How can I make my component iterate recursively to render the desired output? The input array can contain any number of elements and nesting.

Thanks!

0

3 Answers 3

0

update

With the introduction of @NgModule and the migration of directives to @NgModule forwardRef shouldn't be necessary anymore.

original

<my-item *ngFor="let itm of items" [id]="itm.id" [text]="itm.text" [items]="itm.items" >
</my-item>
@Component({
  selector: 'my-item',
  styles: ['div {padding-left: 32px;}']
  providers: [],
  template: `<div>{{id}} - {{text}}
    <my-item *ngFor="let itm of items" [id]="itm.id" [text]="itm.text" [items]="itm.items" >
    </my-item>
    </div>

  `,
  directives: [forwardRef(()=> ItemComponent)]
})
export class ItemComponent {
  @Input() id: string;
  @Input() text: string;
  @Input() items: any[];
  constructor() {
  }
}

forwardRef is required because the class ItemComponent is referenced before it is declared.

Plunker example

Sign up to request clarification or add additional context in comments.

Comments

0

I would create your component this way:

@Component({
  selector: 'my-item',
  template: `
    <div id="data.id" text="data.def"></div>
    <my-item *ngFor="let item of items" [data]="item"></my-item>
  `
})
export class MyItemComponent {
  @Input() data: any;
}

and call it the component from another component and provide the whole component data:

@Component({
  selector: 'other-comp',
  template: `
    <my-item [data]="data" *ngFor="let data of wholeData"></my-item>
  `
})
export class OtherComponent {
  wholeData = [
    {
      "id": 1,
      "text": "abc"
    },
    (...)
  ];
}

1 Comment

Does that load the whole array recursively through all the nested elements? It seems to only go to the 2nd level.
-1

Heres something to get your started. You need to implement the HTML returning function yourself:

  var a = [
  {
    "id": 1,
    "text": "abc"
  },
  {
    "id": 2,
    "text": "def",
    items: [
      {
        "id": 21,
        "text": "def-1",
        items: [
          {
            "id": 211,
            "text": "def-1-1"
          },
          {
            "id": 212,
            "text": "def-1-2"
          }
        ]
      },
      {
        "id": 22,
        "text": "def-2"
      }
    ]
  }
];

function iterateRecursive(array) {
    for(var i = 0; i < array.length; i++) {
    if(array[i].items) {
        console.log(array[i].text);
      //uncomment: printHtml(array[i].id, array[i].text);
        iterateRecursive(array[i].items)
    } else {    
        console.log(array[i].text);         
    }

  }
}


iterateRecursive(a);

//implement this function that takes an id and text and returns html
//call it in place of console log
function printHtml(id, text) {

}

2 Comments

But I need to solve this problem in Angular 2 component loading, not just with javascript. It's no problem just iterating through the recursive array in javascript. The problem is rendering the output through a Angular 2 component.
As stated by Niner too, your solution does not relate to Angular2+.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.