NgbDatePicker-如何将longDate字符串绑定到[ngModel]? [英] NgbDatePicker - How to bind longDate string to [ngModel]?

查看:64
本文介绍了NgbDatePicker-如何将longDate字符串绑定到[ngModel]?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试将格式为"longDate"字符串的日期绑定到ngbDatePicker中的[ngModel]输入值.例如,当用户选择一个日期时,我想显示"2017年1月15日",而不是"2017-01-15".

I am trying to bind a date formatted as a "longDate" string to the [ngModel] input value in ngbDatePicker. For example, when the user picks a date, I'd like to display "January 15, 2017" instead of "2017-01-15".

我知道[ngModel]仅绑定到NgbDateStruct类型的对象,并且在我看来,当我将NgbDateStruct类型的对象(如下面的代码所示,将其称为selectedStartDate)传递给[ngModel]时,然后是NgbDateParserFormatter.在后台调用format(selectedStartDate)以将日期显示为"yyyy-MM-dd".那么如何将longDate格式(即2017年1月15日)绑定到[ngModel]?我曾考虑过重写NgbDateParserFormatter中的format()方法以根据需要显示日期,但是我不确定在传递NgbDateStruct对象绑定到[ngModel]时如何调用日期.

I understand that [ngModel] binds to an object of type NgbDateStruct only, and it seems to me that when I pass an object of type NgbDateStruct (let's call it selectedStartDate as shown in code below) to [ngModel] then NgbDateParserFormatter.format(selectedStartDate) gets called behind the scenes to display the date as "yyyy-MM-dd". So how can I bind a longDate format (i.e. January, 15, 2017) to [ngModel]? I've thought about overriding the format() method in NgbDateParserFormatter to display the date as I want it, but I am not sure how/if it would get called when I pass an NgbDateStruct object to bind to [ngModel].

此外,最好还是保留NgbDateStruct解析/格式化方法,因为我将Date数据作为"yyyy-MM-dd"字符串传递给了API,这些都派上了用场. .18.任何帮助表示感谢!

In addition it would be nice to keep the NgbDateStruct parse/format methods as they come because I am passing Date data as "yyyy-MM-dd" strings to an API and these come in handy.. I am using ngbootstrap alpha.18. Any help appreciated thanks!

<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>

更新: 虽然以下解决方案有效,但由于某些原因,我无法设置默认日期值.例如,从我的日期选择器所在的组件中,我正在ngOnInit()中实现OnInit和form,我将我的"selectedStartDate"绑定字段设置为NgbDateStruct类型的日期.然后,在调试模式下,我可以看到我的selectedStartDate字段被填充,最终MyNgbDateParserFormatter.format()被调用以将日期格式化为"longDate"字符串-但是format()方法中的date参数为null,并且当然会引发错误……我不知道为什么它会以null的形式到达那里.然后,当我选择一个日期时,"selectedDate"将以预期的"longDate"格式显示.

UPDATE: While the solution below works, for some reason I am unable to set a default date value. For example, from the component where my date picker resides, I am implementing OnInit and form within ngOnInit() I am setting my "selectedStartDate" binding field to a date of type NgbDateStruct. Then while in debug mode, I am able to see my selectedStartDate field get populated, and eventually MyNgbDateParserFormatter.format() gets called to format the date into a "longDate" string - however the date parameter within the format() method is null and an error is of course thrown... I can't figure out why it's getting there as null. Afterwards when I select a date then the "selectedDate" is displayed in "longDate" format as expected.

我注意到的下一个问题是,现在每次选择日期时,都不会触发selectStartDate()方法.

The next issue I have noticed is that now every time I select a date, the method selectStartDate() isn't getting fired.

这是我的模块(我在共享模块"中提供此模块,因为这是声明使用ngbdatepicker的组件的地方)

Here is my module (I am providing this in a 'shared module' because that's where my component using the ngbdatepicker is declared)

    @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 { }

这是我的组成部分(重要的部分):

Here is my component (the parts that matter):

    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);
        }
    }

这是我的日期过滤服务:

Here is my date filter service:

    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);
    }
}

谢谢您的任何帮助,谢谢.

Thank you for any help in advance, thanks.

推荐答案

我认为您使用覆盖NgbDateParserFormatter的方法是正确的.您想要创建自己的ParserFormatter实现,并将选择的日期格式作为.format()函数的一种输出.同样,您可以覆盖.parse()函数以采用您选择的日期格式,并将其转换为NgbDateStruct.如果您想为服务器使用其他格式,那么我建议您也为此创建一个函数.我在这里创建了一个示例代码:

I think you are on the right track with overriding NgbDateParserFormatter. You want to create your own ParserFormatter implementation with the date format of choice as the one output by the .format() function. Similarly you override the .parse() function to take in your date format of choice and convert it to NgbDateStruct. If you want to have another format for the server then I suggest you create a function for that as well. I have create an example plunker here:

plnkr

如图所示,第一步是扩展NgbDateParserFormatter并覆盖提到的两个函数:

As shown the first step is to extend the NgbDateParserFormatter and overwrite the two functions mentioned:

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中,您需要提供以下新实现:

In your AppModule then you need to provide this new implementation:

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

然后,您的ngbDatepickers将使用此版本的parse()和format()函数.您还可以在需要时调用formatForServer()函数:

Your ngbDatepickers will then use this version of the parse() and format() functions. You can also call your formatForServer() function when needed:

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);
  }
}

这篇关于NgbDatePicker-如何将longDate字符串绑定到[ngModel]?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆