Javascript Angular2 给动态元素添加 HTML

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/43682801/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 02:06:09  来源:igfitidea点击:

Angular2 add HTML to dynamic elements

javascripthtmlangularjs

提问by Daniel S

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 Angular2to add HTML to the .dynamically_created_div? Because the above only adds to the end of the HTML of the component.

Angular2 中有什么方法可以将 HTML 添加到.dynamically_created_div? 因为上面只添加到组件的 HTML 的末尾。

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

但它不起作用,因为@ViewChild 指令必须在函数之外,我无法再控制它

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.

我不能做的事情是因为我的内容是动态的并且使用唯一的 ID,我不能动态地使用 [innerHtml](它只适用于我第一次放入它们的内容,然后任何其他更改都不能再使用 innerHtml。

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

我检查了Angular2: Insert a dynamic component as a child of a container in the DOM但有同样的问题,占位符不是动态的

UPDATE:

更新:

My code is a little bit more complex:

我的代码有点复杂:

TS:

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:

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 ngForbut now I get

我试图只使用ngFor但现在我得到了

Cannot set property 'cases' of undefined

采纳答案by Max Koretskyi

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>

回答by fastAsTortoise

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

您可以使用 ngfor 并在其中创建元素,使用索引可以创建不同的 ID 和名称。我做了这样的事情我不知道你是否想这样做但这是我的代码来动态创建一些输入并添加或访问它们的值

<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>