简体   繁体   中英

Angular 5 click event on cloned DOM structure not triggering

So I have a hidden DOM structure that I will make visible when clicking on a button (to add some input fields). Now I also want to remove those input fields if not necessary anymore. This is my structure that I clone with jQuery:

<ul id="CTcontainer" class='hidden removeContainer'>
  <li>
    <label>Content Type Name:</label>
    <input class="json-input" type="text" name="CT_name">
  </li>
  <li>
    <label>Content Type Group:</label>
    <input class="json-input" type="text" name="CT_group">
  </li>
  <li *ngIf="contentTypeArray.length != '0'">
    <label>Inherit from Content Type:</label>
    <select class="json-input" name="CT_contentTypeInherit">
      <option *ngFor="let ct of contentTypeArray">{{ ct.name }}</option>
    </select>
  </li>
  <li>
    <button type="button" class="btnSubmit" (click)="removeThisCT($event)">Remove these ContentType input fields</button>
  </li>
</ul>  

Clicking on the "add" button:

public addNewCT(event: Event) {
    $('#ContentTypes').append($('#CTcontainer').clone(true, true).removeAttr('id').removeClass('hidden'));
}  

When then clicking on the button it should fire this:

public removeThisCT(event: Event) {
    alert('testclick');
    console.log('testclick');
    // $(this).closest('.removeContainer').remove();
}  

But nothing happens, debugging in dev tools also shows I'm not entering the function when clicking the button. It seems like my event isn't cloned with? Looking at jQuery .clone() it said to add (true, true) to clone with dataAndEvents and deep events etc. but seemingly doesn't work?

Is this because it's an angular on click event and not a jquery .on('click',) event?

Angular will compile your whole template into javascript to make it fast loading, easy to compress, able to deliver your app as a single file and so forth. More importantly in your case, adding angular template code on the fly will not work, since you are completely bypassing the angular compiler.

As a rule of thumb; when you're writing jquery to manipulate the DOM, you should really question yourself if this really is what you want, and if there's no Angular way of dong it. For a start, all component included in an ngIf or ngFor will be removed completely from the dom once the ngIf turns false or the ngFor does not contain the same numer of elements no more. Use them, and ditch the jquery.

If you want to include whole sets of logic dynamically, read this specific part of the guide: https://angular.io/guide/dynamic-component-loader

A little piece of code that might help you:

<ul *ngIf="cts.length > 0">
  <ng-template ngFor let-ct [ngForOf]="cts">
     <li>
       <label>Content Type Name:</label>
       <input class="json-input" type="text" name="CT_name">
     </li>
     <li>
       <label>Content Type Group:</label>
       <input class="json-input" type="text" name="CT_group">
     </li>
     <li *ngIf="contentTypeArray.length != '0'">
       <label>Inherit from Content Type:</label>
       <select class="json-input" name="CT_contentTypeInherit">
         <option *ngFor="let ct of contentTypeArray">{{ ct.name }}</option>
       </select>
     </li>
     <li>
       <button type="button" class="btnSubmit" 
 (click)="removeThisCT($event)">Remove these ContentType input fields</button>
     </li>
  </ng-template>`
</ul>  

adding a ct (whatever that may mean, don't use abreviations in code)

public addNewCT(event: Event) {
   this.cts.push({name: 'new ct'});
}  

public removeCT(event: Event) {
   this.cts = [...this.cts.filter(ct => ct.name != event.name)];
}  

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