2017-01-15 5 views
3

Я пытаюсь привязать дату, отформатированную как строку longDate, к входному значению [ngModel] в ngbDatePicker. Например, когда пользователь выбирает дату, я бы хотел отобразить «15 января 2017 года» вместо «2017-01-15».NgbDatePicker - Как связать строку longDate с [ngModel]?

Я понимаю, что [ngModel] привязывается к объекту только типа NgbDateStruct, и мне кажется, что, когда я передать объект типа NgbDateStruct (назовем его selectedStartDate, как показано в коде ниже), чтобы [ngModel], а затем NgbDateParserFormatter .format (selectedStartDate) вызывается за кулисами, чтобы отобразить дату как «yyyy-MM-dd». Итак, как я могу привязать формат longDate (т. Е. 15 января 2017 г.) к [ngModel]? Я думал об переопределении метода format() в NgbDateParserFormatter, чтобы отобразить дату, когда я ее хочу, но я не уверен, как/если она будет вызвана, когда я передаю объект NgbDateStruct для привязки к [ngModel].

Кроме того, было бы неплохо сохранить методы анализа/формата NgbDateStruct, поскольку они приходят, потому что я передаю данные Date как строки «yyyy-MM-dd» в API, и это пригодится. Я использую ngbootstrap alpha.18. Любая помощь приветствуется!

<div class="form-group">From: 
    <div class="input-group"> 
     <input class="form-control" 
       name="dp1" 
       [ngModel]="selectedStartDate" 
       (ngModelChange)="selectStartDate($event)" 
       ngbDatepicker 
       [dayTemplate]="customDay" 
       [markDisabled]="isDisabled" 
       #d1="ngbDatepicker" /> 
     <div class="input-group-addon" (click)="d1.toggle()"> 
      <img src="img/calendar-icon.svg" style="width: 1.2rem; height: 1rem; cursor: pointer;" /> 
     </div> 
    </div> 
</div> 

UPDATE: Хотя решение ниже работ, по какой-то причине я не могу установить значение по умолчанию дату. Например, из компонента, в котором находится мой выбор даты, я реализую OnInit и формируюсь внутри ngOnInit() Я устанавливаю свое поле привязки «selectedStartDate» к дате типа NgbDateStruct. Затем, находясь в режиме отладки, я могу видеть, что поле selectedStartDate заполняется, и в итоге MyNgbDateParserFormatter.format() вызывается для форматирования даты в строку «longDate», однако параметр date в методе format() имеет значение null и ошибка, конечно, выбрасывается ... Я не могу понять, почему она попадает туда как null. Впоследствии, когда я выбираю дату, «selectedDate» отображается в формате «longDate», как ожидалось.

Следующая проблема, я заметил, что теперь каждый раз, когда я выбираю дату, метод selectStartDate() не запускается.

Вот мой модуль (я обеспечиваю это в «общий модуль», потому что там мой компонент, используя ngbdatepicker объявлен)

@NgModule({ 
    imports: [ 
     CommonModule, 
     FormsModule, 
     NgbModule, 
     ChartsModule 
    ], 
    exports: [ 
     CommonModule, 
     FormsModule, 
     NgbModule, 
     CrgbFilterComponent, 
     DateFilterComponent, 
     BarChartComponent, 
     LineChartComponent, 
     ChartsModule 
    ], 
    declarations: [ 
     CrgbFilterComponent, 
     DateFilterComponent, 
     BarChartComponent, 
     LineChartComponent 
    ], 
    providers: [ 
     { 
      provide: NgbDateParserFormatter, 
      useFactory:() => { return new CustomNgbDateParserFormatter("longDate") } 
     }, 
     DateFilterService, 
     BarChartService, 
     TableService, 
     HelperMethodsService 
    ] 
}) 
export class SharedModule { } 

Вот мой компонент (те части, которые имеют значение):

export class DateFilterComponent implements OnInit { 

selectedStartDate: NgbDateStruct; 
selectedEndDate: NgbDateStruct; 
@Output() startDateChanged: EventEmitter<string>; 
@Output() endDateChanged: EventEmitter<string>; 

    constructor(private dateFilterService: DateFilterService) { 
     this.startDateChanged = new EventEmitter<string>(); 
     this.endDateChanged = new EventEmitter<string>(); 
    } 

ngOnInit(): void { 
     this.selectStartDate(this.dateFilterService.setDefaultStartDate()); 
     this.selectEndDate(this.dateFilterService.setDefaultEndDate()); 
    } 

selectStartDate(date: NgbDateStruct) { 
     if (date != null) { 
      this.selectedStartDate = date; 
      let dateString = this.dateFilterService.toServerString(date);; 
      this.startDateChanged.emit(dateString); 
     } 
    } 

selectEndDate(date: NgbDateStruct) { 
     if (date != null) { 
      this.selectedEndDate = date; 
      let dateString = this.dateFilterService.toServerString(date); 
      this.endDateChanged.emit(dateString); 
     } 
    } 

Вот моя служба дата фильтра:

export class DateFilterService { 

    constructor(private parserFormatter: NgbDateParserFormatter) { } 

    setDefaultStartDate(): NgbDateStruct { 
     // removing for simplicity, returning a NgbDateStruct object correctly. 
    } 

    setDefaultEndDate(): NgbDateStruct { 
     // removing for simplicity, returning a NgbDateStruct object correctly. 
    } 

    toNgbDateStruct(date: string): NgbDateStruct { 
     return this.parserFormatter.parse(date); 
    } 

    tolongDateString(date: NgbDateStruct): string { 
     return this.parserFormatter.format(date); 
    } 

    toServerString(date: NgbDateStruct): string { 
     return this.parserFormatter.formatForServer(date); 
    } 
} 

Спасибо за любой помогите заранее, спасибо.

ответ

3

Я думаю, что вы на правильном пути с переопределением NgbDateParserFormatter. Вы хотите создать свою собственную реализацию ParserFormatter с выбранным форматом даты как один из результатов функции .format(). Аналогично, вы переопределяете функцию .parse(), чтобы выбрать формат даты и преобразовать его в NgbDateStruct. Если вы хотите иметь другой формат для сервера, я также предлагаю вам создать функцию для этого.У меня есть создать пример plunker здесь:

plnkr

Как показал первый шаг заключается в расширении NgbDateParserFormatter и переписать две упомянутые функции:

import { NgbDateParserFormatter, NgbDateStruct } from '@ng-bootstrap/ng-bootstrap'; 
import { DatePipe } from '@angular/common'; 

export class MyNgbDateParserFormatter extends NgbDateParserFormatter { 
    datePipe = new DatePipe('en-US'); 
    constructor(
     private dateFormatString: string) { 
     super(); 
    } 
    format(date: NgbDateStruct): string { 
     if (date === null) { 
      return ''; 
     } 
     try { 
      return this.datePipe.transform(new Date(date.year, date.month - 1, date.day), this.dateFormatString); 
     } catch (e) { 
      return ''; 
     } 
    } 
    formatForServer(date: NgbDateStruct): string { 
     if (date === null) { 
      return ''; 
     } 
     try { 
      return this.datePipe.transform(new Date(date.year, date.month - 1, date.day), 'y-MM-dd'); 
     } catch (e) { 
      return ''; 
     } 
    } 
    parse(value: string): NgbDateStruct { 
     let returnVal: NgbDateStruct; 
     if (!value) { 
      returnVal = null; 
     } else { 
      try { 
       let dateParts = this.datePipe.transform(value, 'M-d-y').split('-'); 
       returnVal = { year: parseInt(dateParts[2]), month: parseInt(dateParts[0]), day: parseInt(dateParts[1]) }; 
      } catch (e) { 
       returnVal = null; 
      } 
     } 
     return returnVal; 
    } 
} 

В вашем AppModule, то вам нужно предоставить это новая реализация:

@NgModule({ 
    imports: [ 
    BrowserModule, 
    FormsModule, 
    ReactiveFormsModule, 
    JsonpModule, 
    NgbModule.forRoot() 
    ], 
    declarations: [ 
    App, 
    NgbdDatepickerPopup 
    ] 
    bootstrap: [ App ], 
    providers: [ 
    {provide: NgbDateParserFormatter, useFactory:() => new MyNgbDateParserFormatter('longDate')} 
    ] 
}) 
export class AppModule {} 

Ваш ngbDatepickers будет использовать эту версию синтаксического анализа() и формат() ФУНКЦИИ нс. Вы также можете вызвать функцию formatForServer(), если необходимо:

import {Component} from '@angular/core'; 
import { NgbDateParserFormatter } from '@ng-bootstrap/ng-bootstrap'; 
@Component({ 
    selector: 'ngbd-datepicker-popup', 
    templateUrl: 'src/datepicker-popup.html' 
}) 
export class NgbdDatepickerPopup { 
    model; 
    constructor(
    private ngbDateParserFormatter: NgbDateParserFormatter 
) {} 
    getServerDate(dateStruct) { 
    return this.ngbDateParserFormatter.formatForServer(dateStruct); 
    } 
} 
+0

dmungin, спасибо тонну за ваш ответ, это решило мою проблему. Часть, о которой я не думал, это то, как вы предоставляете новый расширенный класс в модуле приложения. –

 Смежные вопросы

  • Нет связанных вопросов^_^