多个Datepicker在一个形式Angular2与差异组件

时间:2017-07-10 05:24:00

标签: angular typescript datepicker

我有一个问题,即在一个带有差异组件的表单中创建多个datepicker。 这是示例代码
https://embed.plnkr.co/nRCpS4/

问题是如果我点击另一个输入栏第一个日期选择器不想关闭,我认为因为nativeElement.contains检测到另一个输入栏是同一个元素。

有人可以帮我解决问题吗?

3 个答案:

答案 0 :(得分:3)

我最喜欢的解决方案就是创建我自己的组件,扩展库提供的组件以满足我的需求。然后,同时处理2个组件上的事件没有任何问题,因为它们每个都是由他自己完成的。它还可以帮助我避免在我的上层组件中出现重复代码。这是我的plnkr:https://plnkr.co/edit/zyxJOiliVbi4lym7lAy9

@Component({
  selector: 'my-date-picker',
  template: `<div class="input-group">
              <input class="form-control" placeholder="yyyy-mm-dd" [name]="name" [(ngModel)]="model" (ngModelChange)="onModelChange()" ngbDatepicker #dp="ngbDatepicker" required>
              <div class="input-group-addon" (click)="dp.toggle();">
                  <i class="fa fa-calendar" aria-hidden="true"></i>
              </div>
            </div>`,
  providers: [
    { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => MyDatePickerComponent), multi: true }]
})
export class MyDatePickerComponent implements ControlValueAccessor {
  @Input() name: string = '';
  @Input() model: any;
  @ViewChild('dp') dp;
  private propagateChange:any = () => {};

  constructor(private _eref: ElementRef) { }

  @HostListener('document:click', ['$event'])
  onClick(event) {
    if (this._eref.nativeElement.contains(event.target)) return true;
    setTimeout(() => this.dp.close(), 10);
  }

  onModelChange() {
    this.propagateChange(this.model);
  }

  writeValue(value) {
      this.model = value;
  }

  registerOnChange(fn) {
    this.propagateChange = fn;
  }

  registerOnTouched() {}
}

如果您不熟悉该代码,请阅读:https://blog.thoughtram.io/angular/2016/07/27/custom-form-controls-in-angular-2.html

通过使用这段代码,我可以使用我的日期选择器:

<my-date-picker name="dp1" [(ngModel)]="newItem.EndTime"></my-date-picker>
<my-date-picker name="dp2" [(ngModel)]="newItem.StartTime"></my-date-picker>

然而,您也可以保留所有代码,并稍微改善您的结算条件:

if (!this._eref.nativeElement.contains(event.target) || !this.dynamicId._elRef.nativeElement.parentNode.contains(event.target)) {
      setTimeout(() => this.dynamicId.close(), 10);
}

答案 1 :(得分:1)

我已更新模板并在(点击)处理程序(click)="d1.toggle(); openDatepicker(d1); closeDatepicker(d2)"中添加了closeDatePicker(dx)函数

因此,当您单击打开d1时,您将显式关闭d2,反之亦然。

  template: `
    <div class="input-group" style="margin-top:50px">
        <input class="form-control" placeholder="yyyy-mm-dd" name="dp1" [(ngModel)]="newItem.EndTime"  ngbDatepicker #d1="ngbDatepicker" required>
        <div class="input-group-addon"  (click)="d1.toggle(); openDatepicker(d1); closeDatepicker(d2)" >
            <i class="fa fa-calendar" aria-hidden="true"></i>
        </div>
    </div>

    <div class="input-group">
        <input class="form-control" placeholder="yyyy-mm-dd" name="dp2" [(ngModel)]="newItem.StartTime"  ngbDatepicker #d2="ngbDatepicker" #d3 required>
        <div class="input-group-addon" (click)="d2.toggle(); openDatepicker(d2); closeDatepicker(d1)" >
            <i class="fa fa-calendar" aria-hidden="true"></i>
        </div>
    </div>
  `

然后您只需将该功能添加到控制器中即可。

  closeDatepicker(id){
    id.close();
  }

这应该可以做到!

答案 2 :(得分:0)

    <div class="input-group" style="margin-top:50px">
    <input class="form-control" placeholder="yyyy-mm-dd" name="dp1" [(ngModel)]="newItem.EndTime"  ngbDatepicker #d1="ngbDatepicker" required>
    <div class="input-group-addon"  (click)="d1.toggle(); d2.toggle(); openDatepicker(d1)" >
        <i class="fa fa-calendar" aria-hidden="true"></i>
    </div>
</div>

<div class="input-group">
    <input class="form-control" placeholder="yyyy-mm-dd" name="dp2" [(ngModel)]="newItem.StartTime"  ngbDatepicker #d2="ngbDatepicker" #d3 required>
    <div class="input-group-addon" (click)="d2.toggle(); d1.toggle(); openDatepicker(d2)" >
        <i class="fa fa-calendar" aria-hidden="true"></i>
    </div>
</div>

尝试在单击下一个按钮时切换其他日期选择器。