Angular 创建重复元素的角度指令

Angular 创建重复元素的角度指令,angular,typescript,directive,angular8,angular-directive,Angular,Typescript,Directive,Angular8,Angular Directive,我有一个Angular指令在大部分情况下都有效,但它在我的元素之后创建了button和ul class=“dropdown”的重复注入。有人知道为什么会重复吗?在普通js中工作良好 我的指示: import { Directive, ElementRef, Renderer2, HostListener, OnInit } from '@angular/core'; @Directive({ selector: '.dropdown-container' }) export class

我有一个Angular指令在大部分情况下都有效,但它在我的元素之后创建了button和ul class=“dropdown”的重复注入。有人知道为什么会重复吗?在普通js中工作良好

我的指示:

 import { Directive, ElementRef, Renderer2, HostListener, OnInit } from '@angular/core';

@Directive({
  selector: '.dropdown-container'
})
export class DropdownDirective implements OnInit {

  constructor(private el: ElementRef, private _renderer: Renderer2) {

  }

  ngOnInit(){

    var dropdown = document.querySelectorAll('.customization-option');
    // /////// Adding li's for each option ////////
    for (var i = 0; i < dropdown.length; i++) {
      var option = dropdown[i].querySelectorAll('option');
      var options = [];
      var drop;
      for (var x = 0; x < option.length; x++) {
        options.push(option[x].innerHTML);
      }

      drop = "<button>" + options[0] + "</button><ul class='dropdown'>";
      options.forEach(addOptions);
      drop += "</ul>";
      console.log(drop);
      dropdown[i].insertAdjacentHTML('afterend', drop)
    }

    function addOptions(value) {
      drop += "<li>" + value + "</li>";
    }


  }

  @HostListener('click') onClick(e) {

    var thisDrop = this.el.nativeElement;
    var opt = thisDrop.querySelector('.dropdown').children;
    var buttonDrop = thisDrop.parentElement.parentElement.querySelector('button');
    thisDrop.classList.toggle("active");


    for (var i = 0; i < opt.length; i++) {
      opt[i].addEventListener('click', function () {
        var optValue = this.innerHTML;
        buttonDrop.innerHTML = optValue;
        this.parentElement.classList.remove('active');
      });
    }

  }

}
import{Directive,ElementRef,Renderer2,HostListener,OnInit}来自“@angular/core”;
@指示({
选择器:'.dropdown容器'
})
导出类DropdownDirective实现OnInit{
构造函数(private el:ElementRef,private\u呈现器:render2){
}
恩戈尼尼特(){
var dropdown=document.querySelectorAll('.customization option');
////为每个选项添加li////////
对于(变量i=0;i”;
期权。forEach(addOptions);
下降+=“”;
控制台日志(drop);
下拉列表[i]。insertAdjacentHTML('afterend',drop)
}
函数addOptions(值){
下降+=“
  • ”+“值+”
  • ”; } } @HostListener('click')onClick(e){ var thisDrop=this.el.nativeElement; var opt=thisDrop.querySelector('.dropdown').children; var buttonDrop=thisDrop.parentElement.parentElement.querySelector('button'); thisDrop.classList.toggle(“活动”); 对于(变量i=0;i
    在我的模板中:

    <form [formGroup]="storeRequest">
      <div class="container">
        <h4>What can we do for you?</h4>
    
        <div class="col-2-container">
          <div class="fieldset">
            <div class="dropdown-container" appDrop>
              <label for="topic">Choose a Topic*</label>
              <select name="topic" id="topic" class="customization-option" (change)="toggleForm($event)">
                <option value="Become a Sponsor" selected>Become a Sponsor</option>
                <option value="Host a Fundraising Event">Host a Fundraising Event</option>
                <option value="Give a Donation">Give a Donation</option>
                <option value="General Information">General Information</option>
              </select>
            </div>
          </div>
        </div>
    
    
        <div class="col-2-container">
          <div class="fieldset">
            <label for="stCompany" appFocus>Company</label>
            <input type="text" name="company" id="stCompany" autocomplete="on" appFocus />
          </div>
        </div>
    
        <div class="col-2-container">
          <div class="fieldset">
            <label for="stFirstname" appFocus>First Name*</label>
            <input type="text" name="firstname2" id="stFirstname" autocomplete="on" appFocus formControlName="stFirstname" />
            <span *ngIf="!storeRequest.get('stFirstname').valid && storeRequest.get('stFirstname').touched" class="validation-error">Please enter your first name.</span>
          </div>
          <div class="fieldset">
            <label for="stLastname" appFocus>Last Name*</label>
            <input type="text" name="stLastname" id="stLastname" autocomplete="on" appFocus formControlName="stLastname" />
            <span *ngIf="!storeRequest.get('stLastname').valid && storeRequest.get('stLastname').touched" class="validation-error">Please enter your last name.</span>
          </div>
        </div>
    
        <div class="col-2-container">
          <div class="fieldset">
            <label for="stAddress1" appFocus>Address Line 1*</label>
            <input type="text" name="stAddress1" id="stAddress1" autocomplete="on" appFocus formControlName="stAddress1" />
            <span *ngIf="!storeRequest.get('stAddress1').valid && storeRequest.get('stAddress1').touched" class="validation-error">Please enter your address.</span>
          </div>
          <div class="fieldset">
            <label for="stAddress2" appFocus>Address Line 2</label>
            <input type="text" name="stAddress2" id="stAddress2" autocomplete="on" appFocus formControlName="stAddress2" />
          </div>
        </div>
    
        <div class="col-2-container">
          <div class="fieldset city">
            <label for="stCity" appFocus>City*</label>
            <input type="text" name="stCity" id="stCity" autocomplete="on" appFocus formControlName="stCity" />
    
          </div>
    
    
    
            <div class="fieldset zip">
    
              <label for="stZip" appFocus>Zip Code*</label>
              <input type="text" name="stZip" id="stZip" autocomplete="on" appFocus formControlName="stZip" />
              <span *ngIf="!storeRequest.get('stZip').valid && storeRequest.get('stZip').touched" class="validation-error">Please enter your zip code.</span>
    
            </div>
          </div>
    
        </div><!--Col-2 end-->
    
        <div class="col-2-container">
          <div class="fieldset">
            <label for="stEmail" appFocus>Email*</label>
            <input type="email" name="stEmail" id="stEmail" autocomplete="on" appFocus formControlName="stEmail" />
            <span *ngIf="!storeRequest.get('stEmail').valid && storeRequest.get('stEmail').touched" class="validation-error">Please enter your valid email.</span>
          </div>
          <div class="fieldset">
            <label for="stPhone" appFocus>Phone Number*</label>
            <input type="tel" name="stPhone" id="stPhone" autocomplete="on" appFocus formControlName="stPhone" />
            <span *ngIf="!storeRequest.get('stPhone').valid && storeRequest.get('stPhone').touched" class="validation-error">Please enter your valid phone.</span>
          </div>
    
        </div>
    
        <h4>Best time to contact you?*</h4>
    
        <div class="col-2-container">
          <div class="fieldset">
            <div class="dropdown-container" appDrop>
              <label for="bestTime">Select a Time*</label>
              <select name="bestTime" id="bestTime" class="customization-option">
                <option value="Morning" selected>Morning</option>
                <option value="Afternoon">Afternoon</option>
                <option value="Evening">Evening</option>
              </select>
            </div>
          </div>
        </div>
    
        <h4 *ngIf="!general">Does the organization have a 501 (c)3 Status?</h4>
        <div *ngIf="!general" class="col-2-container">
          <div class="radios-container">
            <div class="radio-round">
              <input type="radio" checked class="radio" name="c3" id="yes501" />
              <label for="yes501">Yes</label>
            </div>
            <div class="radio-round">
              <input type="radio" class="radio" name="c3" id="no501" />
              <label for="no501">No</label>
            </div>
          </div>
        </div>
    
    
    
    
    
        <h4>What makes your organization a great fit for Zaxby's?</h4>
    
        <div class="">
          <textarea rows="8"></textarea>
        </div>
    
        <br />
        <div class="required">*Required</div>
        <div class="button-container">
          <button class="button gray">Cancel</button>
          <button class="button red">Submit</button>
        </div>
    
      </div>
    </form>
    
    
    我们能为您做些什么?
    选择一个主题*
    成为赞助商
    举办募捐活动
    捐款
    一般资料
    单位
    名字*
    请输入您的名字。
    姓*
    请输入您的姓氏。
    地址行1*
    请输入您的地址。
    地址行2
    城市*
    邮政编码*
    请输入您的邮政编码。
    电子邮件*
    请输入您的有效电子邮件。
    电话号码*
    请输入您的有效电话。
    联系你的最佳时间*
    选择一个时间*
    早晨
    下午
    傍晚
    该组织是否具有501(c)3状态?
    对
    不
    是什么使您的组织非常适合Zaxby的?
    
    *必需的 取消 提交

    它在大多数情况下都能工作,但每次下拉后我都会创建2个按钮和2个ul。有什么建议吗?提前谢谢

    就我所看到的代码而言,您在两个
    选项中使用了
    .customization选项。因此,当您在
    querySelectorAll('.customization option')
    中循环时,它会使用
    下拉列表.length进行两次迭代,创建值的副本

    在这种情况下,如果您只需要访问第二个
    选项的类,那么只需传递索引并访问元素即可

    document.querySelectorAll('.customization-option')[1];
    

    谢谢你,安吉拉。你给我指明了正确的方向。我换了

    document.querySelectorAll('.customization-option');
    

    在将el定义为ElementRef之后

    constructor(public el: ElementRef, private _renderer: Renderer2) {
        this.el = el;
      }
    
    constructor(public el: ElementRef, private _renderer: Renderer2) {
        this.el = el;
      }