简体   繁体   中英

Angular 8 - Dynamically added button.Click event not working

I am trying to add product images on clicking the add button in screen and to remove using delete button. These should be loaded dynamically when user clicks add or delete button. But when I dynamically inject html and bind click event it's not working. On clicking it, function is not calling. I have simplified the code below. HTML file:

<div class="product_images">
          <div class="imageHeading">
                        <p>
                            Images
                        </p>
                    </div>
                    <div class="kt-form__group">
                        <div class="row">
                            <div class="col-lg-2 imageLabel">Main Image</div>
                            <div class="col-lg-3 imageLabel">Choose Image</div>
                            <div class="col-lg-2 imageLabel">Image</div>
                            <div class="col-lg-2 imageLabel">Actions</div>
                        </div>
                    </div>
                    <div class="imagesContainer" [innerHtml]="containerToAdd | sanitizeHtml">
                    </div>
                </div>

Ts file

// Angular
import { Component, OnInit, ElementRef, ViewChild, ChangeDetectionStrategy, OnDestroy, ChangeDetectorRef } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
// Material
import { SelectionModel } from '@angular/cdk/collections';
import { MatPaginator, MatSort, MatSnackBar, MatDialog, MatRadioButton } from '@angular/material';
import { ProductManagementService } from '../../../../../core/e-commerce/_services/product-management.service';
import { ToastrService } from 'ngx-toastr';
import { ViewEncapsulation } from '@angular/core';

@Component({
  selector: 'kt-product-edit',
  templateUrl: './product-edit.component.html',
  styleUrls: ['./product-edit.component.scss'],
  encapsulation: ViewEncapsulation.None
})
export class ProductEditComponent implements OnInit {

previewUrl : any = "/assets/media/images/noimage.jpg";
containerToAdd : string = "";

constructor(
    private products: ProductManagementService,
    private router: Router,
    private route: ActivatedRoute,
    private toastr: ToastrService,
    private cdr: ChangeDetectorRef,
    private FB: FormBuilder,
    ) {

    }
 ngOnInit() {
    this.addImage();
}
addImage(){
     this.containerToAdd = `
      "<div class="kt-form__group image-container container-1">
          <div class="row">
              <div class="col-lg-2"><input type="checkbox" /></div>
              <div class="col-lg-3"><input type="file" accept="image/*" (change)="imagePreview($event)" /></div>
              <div class="col-lg-2"><img [src]="previewUrl" class="prod_image" /></div>
              <div class="col-lg-2">
                  <span class="deleteElement" (click)="deleteImage()">
                    Del
                  </span>
              </div>
          </div>
      </div>"`;
  }
  deleteImage() {
    console.log("deleteImage");
  }
}

When I click that span with that click event, deleteImage() function is not calling.

You are binding to the innerHtml so any angular syntax in the html you are using for binding is not going to work as it is not a compile angular template. So your click binding is invalid. A simple *ngIf should be good.

<div class="product_images">
    <div class="imageHeading">
        <p>
            Images
        </p>
    </div>
    <div class="kt-form__group">
        <div class="row">
            <div class="col-lg-2 imageLabel">Main Image</div>
            <div class="col-lg-3 imageLabel">Choose Image</div>
            <div class="col-lg-2 imageLabel">Image</div>
            <div class="col-lg-2 imageLabel">Actions</div>
        </div>
    </div>
    <div class="imagesContainer" [innerHtml]="containerToAdd | sanitizeHtml">
        <div class="kt-form__group image-container container-1" *ngIf="addImage">
            <div class="row">
                <div class="col-lg-2">
                    <input type="checkbox" />
                </div>
                <div class="col-lg-3">
                    <input type="file" accept="image/*" (change)="imagePreview($event)" />
                </div>
                <div class="col-lg-2"><img [src]="previewUrl" class="prod_image" /></div>
                <div class="col-lg-2">
                    <span class="deleteElement" (click)="deleteImage()">
                    Del
                  </span>
                </div>
            </div>
        </div>
    </div>
</div>
export class MyComponent{
previewUrl : any = "/assets/media/images/noimage.jpg";
public addImage = false

  constructor(
    private products: ProductManagementService,
    private router: Router,
    private route: ActivatedRoute,
    private toastr: ToastrService,
    private cdr: ChangeDetectorRef,
    private FB: FormBuilder) {
  }

  ngOnInit() {
    this.addImage();
  }

  addImage(){
     this.addImage = true;
  }

  deleteImage() {
   this.addImage = false
    console.log("deleteImage");
  }
}

EDIT 1:

<div class="product_images">
    <div class="imageHeading">
        <p>
            Images
        </p>
    </div>
    <div class="kt-form__group">
        <div class="row">
            <div class="col-lg-2 imageLabel">Main Image</div>
            <div class="col-lg-3 imageLabel">Choose Image</div>
            <div class="col-lg-2 imageLabel">Image</div>
            <div class="col-lg-2 imageLabel">Actions</div>
        </div>
    </div>
    <div class="imagesContainer">
        <div class="kt-form__group image-container container-1" *ngFor="let image of images; let index = i">
            <div class="row">
                <div class="col-lg-2">
                    <input type="checkbox" />
                </div>
                <div class="col-lg-3">
                    <input type="file" accept="image/*" (change)="imagePreview($event, image)" />
                </div>
                <div class="col-lg-2"><img [src]="previewUrl" class="prod_image" /></div>
                <div class="col-lg-2">
                    <span class="deleteElement" (click)="deleteImage(i)">
                    Del
                  </span>
                </div>
            </div>
        </div>
    </div>
</div>
export class MyComponent{
previewUrl : any = "/assets/media/images/noimage.jpg";
public images = []

  constructor(
    private products: ProductManagementService,
    private router: Router,
    private route: ActivatedRoute,
    private toastr: ToastrService,
    private cdr: ChangeDetectorRef,
    private FB: FormBuilder) {
  }

  ngOnInit() {
    this.addImage();
  }

  addImage(){
     this.images.push({});
  }

  deleteImage(index: number) {
    this.images.splice(index, 1)
    console.log("deleteImage");
  }

  imagePreview($event, image){
    image.path = event.value;
  }
}

i think it helps and you would add some code in your favour:

html :

<div class="product_images">
  <div class="imageHeading">
    <p>
      Images
    </p>
  </div>
  <div class="kt-form__group">
    <div class="row">
      <div class="col-lg-2 imageLabel">Main Image</div>
      <div class="col-lg-3 imageLabel">Choose Image</div>
      <div class="col-lg-2 imageLabel">Image</div>
      <div class="col-lg-2 imageLabel">Actions</div>
    </div>
  </div>
  <div class="imagesContainer" #elementRef>
  </div>
</div>

ts:

@ViewChild("elementRef", { static: true }) deletableItem: ElementRef<
    HTMLDivElement
  >;
  containerToAdd: any;

  previewUrl: any;

  constructor(private sanitizer: DomSanitizer, private renderer: Renderer2) {}

  ngOnInit() {
    this.addImage();
  }

  ngAfterViewInit() {}

  addImage() {
    let span: HTMLSpanElement = this.renderer.createElement("span");
    this.renderer.addClass(span, "deleteElement");
    this.renderer.listen(span, "click", () => {
      console.log("I am going to delete you");
    });
    span.innerHTML = "Del";

    let divHoldsSpan: HTMLDivElement = this.renderer.createElement("div");
    this.renderer.addClass(divHoldsSpan, "col-lg-2");
    this.renderer.appendChild(divHoldsSpan, span);

    let image: HTMLImageElement = this.renderer.createElement("img");
    this.renderer.addClass(image, "prod_image");
    image.src = this.previewUrl;

    let divHoldsImage: HTMLDivElement = this.renderer.createElement("div");
    this.renderer.addClass(divHoldsImage, "col-lg-2");
    this.renderer.appendChild(divHoldsImage, image);

    let imageInput: HTMLInputElement = this.renderer.createElement("input");
    imageInput.type = "file";
    imageInput.accept = "image/*";
    this.renderer.listen(imageInput, "change", event => {
      // console.log("YOUR FILE,SIR:",e.target.files);

      for (let index = 0; index < event.target.files.length; index++) {
        let reader = new FileReader();
        const fileToUpload = event.target.files[index];
        reader.onload = (e: any) => {
          image.src = e.target.result;
        };
        reader.readAsDataURL(event.target.files[index]);
      }
    });

    let divHoldsImageInput: HTMLDivElement = this.renderer.createElement("div");
    this.renderer.addClass(divHoldsImageInput, "col-lg-3");
    this.renderer.appendChild(divHoldsImageInput, imageInput);

    let checkboxInput: HTMLInputElement = this.renderer.createElement("input");
    checkboxInput.type = "checkbox";

    let divHoldsCheckbox: HTMLDivElement = this.renderer.createElement("div");
    this.renderer.addClass(divHoldsCheckbox, "col-lg-2");
    this.renderer.appendChild(divHoldsCheckbox, checkboxInput);

    let divRow: HTMLDivElement = this.renderer.createElement("div");
    this.renderer.addClass(divRow, "row");
    this.renderer.appendChild(divRow, divHoldsCheckbox);
    this.renderer.appendChild(divRow, divHoldsImageInput);
    this.renderer.appendChild(divRow, divHoldsImage);
    this.renderer.appendChild(divRow, divHoldsSpan);

    let divKtForm = this.renderer.createElement("div");
    this.renderer.addClass(divKtForm, "kt-form__group");
    this.renderer.addClass(divKtForm, "image-container");
    this.renderer.addClass(divKtForm, "container-1");
    this.renderer.appendChild(divKtForm, divRow);

    this.renderer.appendChild(this.deletableItem.nativeElement, divKtForm);
  }

  deleteImage() {
    console.log;
  }

stackblitz

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM