13

I have this code:

import { Component, ElementRef, Renderer2 } from '@angular/core';

@Component({
    selector: 'my-app',
    template: '<button (click)="runR()">Run</button>
<div class="testme">
    <div class="somediv">
        <div class="dynamically_created_div unique_identifier"></div>
        <div class="dynamically_created_div unique_identifier"></div>
        <div class="dynamically_created_div unique_identifier"></div>
    </div>
</div>',
})

export class AppComponent{
    hostEl: any;

    constructor(
        private el:ElementRef,
        private renderer:Renderer2,
    )  {
        this.hostEl = el.nativeElement;
    }

    runR(){
        let change_this;
        change_this= this.renderer.createElement('span');
        this.renderer.addClass(change_this, 'change_this');
        this.renderer.appendChild(this.hostEl, change_this);      
    }

}

Is there any way in Angular2 to add HTML to the .dynamically_created_div? Because the above only adds to the end of the HTML of the component.

I also tried with:

import { Component, ElementRef, ViewChild, Renderer, AfterViewInit } from '@angular/core';

@Component({
  selector: 'my-app',
  template: `<button (click)="runR()">Run</button>
<div class="testme">
    <div class="somediv">
        <div class="dynamically_created_div">

        </div>
    </div>
</div>
  `,
})
export class AppComponent {
  constructor(private renderer:Renderer) {}

    runR() {
        @ViewChild('dynamically_created_div') d1:ElementRef;
        this.renderer.invokeElementMethod(this.d1.nativeElement, 'insertAdjacentHTML', ['beforeend', '<div class="new_div">new_div</div>'] );
    }

}

But it's not working because the @ViewChild directive must be outside the function and I can't have control over it anymore

I also tried like this:

<div class="dynamically_created_div" [innerHtml]="newHTML"></div>
this.newHTML = '<div class="new_div">new_div</div>';

Thing I cannot do because my content is dynamic and uses unique IDs and I cannot use [innerHtml] dynamically ( it only works for what I put in themplate for the first time, then anything else that changes can't use innerHtml anymore.

I checked Angular2: Insert a dynamic component as child of a container in the DOM but there is the same problem, the placeholders aren't dynamic

UPDATE:

My code is a little bit more complex:

TS:

import { AfterContentInit, Component, OnInit, OnDestroy, ViewEncapsulation } from '@angular/core';
import { NgForm, FormsModule, ReactiveFormsModule, FormGroup, FormControl, FormBuilder, Validators } from '@angular/forms';
import { SFService } from '../services/sf.service';
import { Injectable, Pipe, PipeTransform } from '@angular/core';

@Component({
    selector: 'my-app',
    templateUrl: './app.component.html',
    providers: [ SFService ],
})

export class AppComponent implements OnInit {
    constructor(
        private sfservice: SFService,
    ) {}

    ngOnInit(){
        this.sfservice.getMembers().subscribe(members => {
            this.members = members.members;
        });
    }


    members: Member[];
    member_selector: Member[];

    member_each: Member;
    member_selector_each: Member[];
    cases: Case;

    runR(){

        this.members.forEach(member_each => {
            this.member_selector.forEach(member_selector_each => {
                if(member_each.Id === member_selector_each.Id){
                    console.log(member_selector_each.Id);
                    this.sfservice.getCaseHistory(member_selector_each.Id, "2017-04-25T00:00:00", "2017-04-28T23:59:59").subscribe(cases => {

                        this.member_each['cases'] = cases;
                        console.log(this.member_each);
                    });
                }
            })
        })
    }
}

HTML:

<form #myForm="ngForm" novalidate>
    <select name="member_selector_name" [(ngModel)]="member_selector" multiple ng-model="selectedValues" style="height:200px;">
        <option *ngFor="let member of members" [ngValue]="member">{{member.Name}}</option>
    </select>
    <button (click)="runR()">Run</button>
</form>

<div id="results">
    <div *ngFor="let mem of members" class="member-card-{{mem.Id}}">
        <div class="card-container">
             <div *ngFor="let case of mem.Cases" class="case-card" id="{{case.Id}}">{{case.Number}}
             </div>
        </div>
    </div>
</div>

I was trying to use only ngFor but now I get

Cannot set property 'cases' of undefined

2 Answers 2

13

What's the problem with this approach?

export class AppComponent{
    @ViewChild('d1') d1:ElementRef;
    @ViewChild('d2') d2:ElementRef;
    @ViewChild('d3') d3:ElementRef;

    constructor(private renderer:Renderer2)  {    }

    runR(){
        let change_this;
        change_this= this.renderer.createElement('span');
        this.renderer.addClass(change_this, 'change_this');
        this.renderer.appendChild(this.d1, change_this);
    }

}

Template:

<div class="dynamically_created_div unique_identifier" #d1></div>
<div class="dynamically_created_div unique_identifier" #d2></div>
<div class="dynamically_created_div unique_identifier" #d3></div>
Sign up to request clarification or add additional context in comments.

10 Comments

I will have more than just one <div class="dynamically_created_div" #dcd> is it possible to select between them ?
I've edited the question to include multiple dynamically_created_div
@DanielS, so add different #dcd identifiers to each or them
could you update your example to reflect that? It would help me to better understand this
that would be an issue as d1, d2, d3 are variable IDs unknown at the moment I write the code, so I cannot hard code them... and they are thousands of IDs, they would be the IDs of the "cards"
|
0

you can use ngfor and create you elements inside it and using index you can create different ids and names. I do something like this i dont know if you want to do the same but here's my code to create some input's dynamically and add or access their values

<div *ngFor="let comp of templateVals | async;let i=index">

  <md-input-container class="example-90" *ngIf="comp.type=='code'">
    <textarea rows="4"  mdInput  name="desc{{i}}" [(ngModel)]="comp.data" placeholder="Description"></textarea>
  </md-input-container>
  <md-input-container class="example-90" *ngIf="comp.type=='text'">
    <textarea rows="4"  mdInput name="text{{i}}" [(ngModel)]="comp.data" placeholder="Text"></textarea>
  </md-input-container>
  <md-input-container class="example-90" *ngIf="comp.type=='title'">
    <input mdInput name="title{{i}}" [(ngModel)]="comp.data" placeholder="Title">
  </md-input-container>
  <span class="example-90" *ngIf="comp.type=='upload'">

    <input-file *ngIf="!comp.data" [acceptId]="comp.id"  (onFileSelect)="addedFileInfo($event)"></input-file>
  <span *ngIf="comp.data">{{comp.data}}</span>

  </span>
  <span class="example-10">
  <button md-mini-fab (click)="removeThis(comp)"><md-icon>remove circle</md-icon></button>
    </span>
</div>

3 Comments

I have no problem to create the elements, but I don't understand how to access them, and how to add HTML to each of them depending on their IDs or Classes
I need to access them in a function so I can do some data manipulation and calculations as well on them, just (click)="removeThis(comp)" will not be enough
just take the index and do you calculations and update that value in templateVals array.

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.