如何解除Angular中的自定义下拉列表?

时间:2017-11-29 20:33:25

标签: angular

我创建了一个自定义控件,该控件将根据输入到文本框中的条件的搜索结果创建<ul>元素。当用户点击或点击下拉列表中的某个项目时,它会选择该项目。但是,如果用户改变主意,我希望能够隐藏<ul>元素。我需要做些什么来捕捉其他地方的点击(现在可见的<li>)元素以隐藏<ul>

如果我有一个FormControl并且我打电话给setValue(),请注意,我需要手动将其标记为脏,以便让父FormGroup变脏。这是正常的,还是在调用setValue()时需要做的事情,以确保值更改在表单树中传播?

更新

我正在添加我的模板和组件代码。 (blur)方法似乎不起作用。可能是因为我在iPad模拟器上进行测试。我没有尝试过不同的浏览器。我正在发布我的模板和组件代码中的重要摘录,看看是否有一些明显的东西,我可以采取不同的方式来获得所需的行为。

模板

...
<div class="defect-detail" [formGroup]="defectForm">
...
  <my-date-picker formControlName="completedDate" [options]="datePickerOptions"></my-date-picker>
...
  <div class="assigned-trade">
    <span class="glyphicon glyphicon-search"></span>
    <input type="text" [formControl]='search' (blur)="showTradesSearchResults = false">
      <ul *ngIf="list$ | async as data" [ngStyle]="{'display' : showTradesSearchResults ? '' : 'none'}">
        <li *ngFor="let trade of data" data-id="{{trade.value}}" (click)="selectTrade(trade)">
          {{trade.text}}
        </li>
      </ul>
  </div>
...
  <div class="repair-status" (click)="showRepairStates = !showRepairStates" (blur)="showRepairStates = false">
    {{repairStatus}}
    <span class="glyphicon glyphicon-chevron-right"></span>
  </div>
  <ul *ngIf="showRepairStates">
    <li *ngFor="let opt of repairStates" (click)="selectRepairState($event)" data-id="{{opt.value}}">{{opt.text}}.    </li>
  </ul>
...
  <button [ngClass]="{'hbp-btn-blue' : !defect.complete}" class="form-control" (click)="complete()" *ngIf="defect.repairStatus == 6">
    Complete
  </button>
...
</div>
...

组件

...
selectRepairState(event) {
  console.log("Selecting Repair State");
  //this.defect.repairStatus = +event.target.id;

  this.defect.complete = false;
  let repairStatus = this.defectForm.get('repairStatus');
  repairStatus.setValue(+event.target.id);
  repairStatus.markAsDirty();
  this.showRepairStates = false;
}

selectTrade(trade) {
  console.log("select trade");
  console.debug(trade);

  let assignedTrade = this.defectForm.get('assignedTrade');
  assignedTrade.setValue(trade);
  assignedTrade.markAsDirty();

  this.search.patchValue(trade.text, { emitEvent: false });
  this.showTradesSearchResults = false;
}
...
complete(): void {
  console.log('Completing ');
  this.defect.complete = true;
  let newDateValue = DatePickerUtil.fromDate(new Date());
  let completedDate = this.defectForm.get('completedDate');
  completedDate.patchValue(newDateValue);
  completedDate.markAsDirty();
}

2 个答案:

答案 0 :(得分:0)

您的第一个问题的答案是您只需要收听blur事件:

<ul *ngIf="showUL"></ul>
...
<div id="parent" (blur)="hideUL()"></div>

hideUL() {
   this.showUL = false;
}

就这么简单。

另一方面,你的第二个问题的答案是否定的,你不应该手动设置脏,这意味着你做错了。

但是如果你想这样做,你应该使用markAsDirty方法,如下所示:

FormControl.markAsDirty();

答案 1 :(得分:0)

您可以使用HostListener装饰器来监听外部的点击事件:

  @HostListener('document:click', ['$event'])
  clickedOutside($event) {
    // here you can hide your dropdown
  }

关于第二个问题,我猜脏标志仅在用户与控件交互时设置。或者您手动设置。