spring
spring

Reputation: 18517

Dynamic instantiation of Components?

Update: To clarify my sad verbiage below...

Given an array of JSON objects, a "Level" component and a "Sprite" component...

I'm stuck on the syntax to loop through the array and init a new "Sprite" for each JSON object and then add that "Sprite" to ... the template (?) of my "Level".

This is my "Level" template. I can hardcode the Sprite in and it works (as the image shows) but I'm scrambling to find the syntax to add an arbitrary number of Sprites.

<div>
  <img src={ {imagePath}}/>
</div>
<div>
  <app-sprite></app-sprite>
</div>


I'm a refugee Flex/Actionscript developer and am learning Angular 2. I "get" lots of it – but then I get stuck.

My little exercise here: based on some JSON (hard-coded now but later to come from a Service) is to populate a "Level" component with a background image, and then create and position some "Sprites" on the "Level".

Here's the way it looks now:
enter image description here

I've created a plunk of what I am doing. Where I am confused:

<div>
  <img class="spriteFloater" src={{imagePath}}/>
</div>`

The above works if I hardcode the "imagePath" to a url – but if I try to use "eventData.imagePath" (where event data is a JSON obj) then it fails.

I can hard-code that a reference to that template into my "Level" ("app-sprite" tags) and it works but my attempts to generate "Sprites" on the fly have failed.

Geez... sorry this is such a stupid, wordy post.

Upvotes: 0

Views: 115

Answers (2)

spring
spring

Reputation: 18517

With Günter's nudge I was able to come up with this. I didn't know the syntax to use *ngFor correctly and then I had to figure out how to apply the passed in data to the style of the newly created sprites.

Guess I am not in Kansas Flex/Actionscript any more. This stuff is crazy... but I like it (I think).

<div>
  <app-sprite *ngFor="let event of eventList" [eventData]="event"
  ></app-sprite>
</div>

enter image description here

import { Component, OnInit, Input } from '@angular/core';
import {Eventdata} from './eventdata'

@Component({
  selector: 'app-sprite',
  template:`
     <div>
         <img class = "spriteFloater" [src]="eventData.imagePath"
                [style.left] = "eventData.x"
                [style.top] = "eventData.y"
                [style.background] = "eventData.id"/>
    </div>`,
  styles [`
    .spriteFloater {
      position: absolute;
      background: black;
      left: 50px;
      top:  80px;
    }
  `]
})
export class Sprite implements OnInit {
  @Input() eventData: Eventdata;
  setEventData(data:EventData){
  }

  constructor() {
  }

  ngOnInit() {

  }

}

Upvotes: 1

G&#252;nter Z&#246;chbauer
G&#252;nter Z&#246;chbauer

Reputation: 658047

I guess you just need to use

eventData?.imagePath

If you init data in ngOnInit() this is after Angular first tries to resolve bindings in the view. If eventData is null the access to imagePath throws. With ?. Angular accesses imagePath only when eventData is != null

Upvotes: 0

Related Questions