将日期范围添加到NgbInputDatepicker输入字段

Win*_*cca 5 typescript ng-bootstrap angular angular5

我正在使用Angular 5.2和ngbootstrap 1.1。该库具有几个不同的datepicker选项,一个用作组件,另一个用作指令。

我正在使用指令。以下是一个如何使用模板设置ngbootstrap指令的示例的链接。

指令示例

选择两个日期后,弹出框会在输入中添加一个日期。

在最初的方法中,我尝试设定

[(ngModel)]=model 
Run Code Online (Sandbox Code Playgroud)

 this.model = `${this.fromDate} / ${this.toDate}`;
Run Code Online (Sandbox Code Playgroud)

但是,我在设置模型后才意识到这一点。该日期是在ngbootstrap的datepicker模块提供的另一个组件内部检查

private _fromDateStruct(date: NgbDateStruct): NgbDate {
  const ngbDate = date ? new NgbDate(date.year, date.month, date.day) : null;
  return this._calendar.isValid(ngbDate) ? ngbDate : null;
}
Run Code Online (Sandbox Code Playgroud)

链接到组件代码

同样,上面的private方法也使得无法扩展类并覆盖检查

class DateInputDirective extends NgbInputDatepicker 
Run Code Online (Sandbox Code Playgroud)

我更深入地挖掘了一下,希望可以改变服务。 NgbDateAdapter服务返回对象,如果不正确,则返回null。我的字符串日期范围不能超过此范围。

NgBootstrap API

fromModel(date: NgbDateStruct): NgbDateStruct {
  return (date && date.year && date.month && date.day) ? {year: date.year, month: date.month, day: date.day} : null;
Run Code Online (Sandbox Code Playgroud)

}

另外,我利用了angular的useClass附加了条件字符串。

{
    provide: NgbDateAdapter,
    useClass: NgbStringAdapter
},
Run Code Online (Sandbox Code Playgroud)

但是,NgbDatePickerInput类在此类最终确定之前会覆盖行为。

不知道我是否缺少一些非常简单的东西,或者是否需要多次使用extends或useClass。但是我绝对是在寻找一些见识。stackblitz链接不是我的实际代码,但可以很好地表示我的工作。如果有不清楚的地方,请随时与我们联系。谢谢!

Fet*_*rij 7

使用ElementRefViewChild设置输入值将起作用。

我的意思是不ViewChild与Directive / Component(NgbInputDatepicker)一起使用,因为对指令中元素的所有访问器都是私有的,除非在_writeModelValue方法(第363行)writeValue调用它,否则我看不到如何更改输入的 内容,但只能更新其中一个日期。

因此,步骤如下:

  • 通过使用ElementRefViewChild具有输入元素,
  • Renderer2设置其值(如指令一样)
  • NgbDateParserFormatter用来格式化模型日期
  • 您只需在选择日期后执行此操作,因此在方法中 onDateSelection

这是主要代码,我将添加一些注释:

HTML:

<input
     #myRangeInput
    class="form-control" 
    placeholder="mm/dd/yyyy"
    name="dp" 
    [(ngModel)]="model" 
    ngbDatepicker 
    [dayTemplate]="t"
    [autoClose]="false"
    [displayMonths]="2"
    [maxDate]="maxDate"
    [minDate]="minDate"
>
    <ng-template #t let-date="date" let-focused="focused">
        <span class="custom-day"
            [class.range]="isFrom(date) || isTo(date) || isInside(date) || isHovered(date)"
            [class.faded]="isHovered(date) || isInside(date)"
            (click)="onDateSelection(date)"
            (mouseenter)="hoveredDate = date"
            (mouseleave)="hoveredDate = null"
            >
        {{ date.day }}
        </span>
    </ng-template>
Run Code Online (Sandbox Code Playgroud)

文字说明:

import {Component, ViewChild, OnInit, ElementRef, Renderer2} from '@angular/core';
import {
    NgbDatepicker, 
    NgbInputDatepicker, 
    NgbDateStruct, 
    NgbCalendar, 
    NgbDateAdapter,
    NgbDateParserFormatter} from '@ng-bootstrap/ng-bootstrap';
...
export class NgbdDatepickerPopup implements OnInit{
  ...
 @ViewChild('myRangeInput') myRangeInput: ElementRef;
 constructor(element: ElementRef, private renderer: Renderer2, private _parserFormatter: NgbDateParserFormatter) { }
 onDateSelection(date: NgbDateStruct) {
        let parsed = ''; // initializing with empty string
        if (!this.fromDate && !this.toDate) {
            this.fromDate = date;
        } else if (this.fromDate && !this.toDate && after(date, this.fromDate)) {
            this.toDate = date;
            this.input.close();
        } else {
            this.toDate = null;
            this.fromDate = date;
        }
        if(this.fromDate) {
          // if fromDate is set: add the first date
          parsed += this._parserFormatter.format(this.fromDate);
        }
        if(this.toDate) {
          // if toDate is set: add the second date with separator
          parsed += ' - ' + this._parserFormatter.format(this.toDate);
        }
        // here we update the input value with the new parsed value
        this.renderer.setProperty(this.myRangeInput.nativeElement, 'value', parsed);
    }
Run Code Online (Sandbox Code Playgroud)

这是有效的演示:https : //stackblitz.com/edit/angular-skbpc8-maun8a