日期选择器的弹出窗口显示错误的年份
Popup from datepicker showing wrong year
angular 中日期选择器的弹出窗口在打开时显示错误的年份。然而,从 2011 年 12 月之后的那一年开始改为 2021 年。
我正在使用 Angular 12.2.0 和 Bootstrap 4.3.1。我无法弄清楚如何更改它。可能是兼容性问题?对不起我只能link图片因为“声望点数”:P
Datepicker
日期-picker.component.html
<div class="input-group input-group-sm">
<input class="form-control" name="dp" [(ngModel)]="selectedDate" ngbDatepicker #d="ngbDatepicker" (change)="onDateChange($event.target.value)" (dateSelect)="onDateSelect($event)" [disabled]="isDisabled ? 'disabled' : null">
<div class="input-group-append" *ngIf="!isDisabled">
<button class="btn btn-input calendar fa fa-calendar" (click)="d.toggle()" type="button"></button>
</div>
</div>
日期-picker.component.ts
import { Component, OnInit, ViewEncapsulation, forwardRef, Injectable, Output, EventEmitter } from '@angular/core';
import { NgbDateParser } from '../../ngb-date-parser';
import { NgbDateParserFormatter, NgbDatepickerI18n, NgbDateStruct } from '@ng-bootstrap/ng-bootstrap';
import { ControlValueAccessor, NG_VALUE_ACCESSOR, } from '@angular/forms';
const I18N_VALUES = {
'it-IT': {
weekdays: ['Lu', 'Ma', 'Me', 'Go', 'Ve', 'Sa', 'Do'],
months: ['Gen', 'Feb', 'Mar', 'Apr', 'Mag', 'Giu', 'Lug', 'Ago', 'Set', 'Ott', 'Nov', 'Dic'],
},
'de-DE': {
weekdays: ['Mo', 'Di', 'Mi', 'Do', 'Fr', 'Sa', 'So'],
months: ['Jan', 'Feb', 'Mar', 'Apr', 'Mai', 'Jun', 'Jul', 'Aug', 'Sep', 'Okt', 'Nov', 'Dez'],
},
'en-US': {
weekdays: ['Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa', 'Su'],
months: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
},
'en-UK': {
weekdays: ['Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa', 'Su'],
months: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
}
};
@Injectable()
export class I18n {
language = localStorage.getItem('locale');
}
// Define custom service providing the months and weekdays translations
@Injectable()
export class CustomDatepickerI18n extends NgbDatepickerI18n {
constructor(private i18n: I18n) {
super();
}
getWeekdayShortName(weekday: number): string {
return I18N_VALUES[this.i18n.language].weekdays[weekday - 1];
}
getMonthShortName(month: number): string {
return I18N_VALUES[this.i18n.language].months[month - 1];
}
getMonthFullName(month: number): string {
return this.getMonthShortName(month);
}
getDayAriaLabel(date: NgbDateStruct): string {
return `${date.day}-${date.month}-${date.year}`;
}
}
export const DATEPICKER_VALUE_ACCESSOR = {
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => DatePickerComponent),
multi: true
};
@Component({
selector: 'app-date-picker',
templateUrl: './date-picker.component.html',
styleUrls: ['./date-picker.component.scss'],
providers: [DATEPICKER_VALUE_ACCESSOR, {provide: NgbDateParserFormatter, useClass: NgbDateParser},
I18n, {provide: NgbDatepickerI18n, useClass: CustomDatepickerI18n}]
})
export class DatePickerComponent implements ControlValueAccessor {
selectedDate: any;
isDisabled = false;
@Output() dateChange = new EventEmitter<any>();
constructor() {}
// Function to call when the date changes.
onChange = (date?: Date) => {
};
// Function to call when the date picker is touched
onTouched = () => {};
writeValue(value: Date) {
if (!value) {
this.selectedDate = undefined;
return;
}
value = new Date(value);
this.selectedDate = {
year: value.getFullYear(),
month: value.getMonth()+1,
day: value.getDate()
}
}
registerOnChange(fn: (date: Date) => void): void {
this.onChange = fn;
}
// Allows Angular to register a function to call when the input has been touched.
// Save the function as a property to call later here.
registerOnTouched(fn: () => void): void {
this.onTouched = fn;
}
// Allows Angular to disable the input.
setDisabledState(isDisabled: boolean): void {
this.isDisabled = isDisabled;
}
// Write change back to parent
onDateChange(value: string) {
const dateString = value.split('.');
if(dateString.length == 3) {
const date: Date = new Date(+dateString[2], +dateString[1]-1, +dateString[0]);
this.onChange(date);
}
if (value == null || value == '') {
this.onChange(null);
}
}
// Write change back to parent
onDateSelect(value: any) {
this.onChange(new Date(value.year, value.month - 1, value.day));
this.dateChange.emit(value);
}
}
不幸的是,我不太确定为什么默认为 2011 年。
但是,在提供更好的答案之前,根据 ngb-datepicker 文档(https://ng-bootstrap.github.io/#/components/datepicker/overview,标题为内容模板的部分),您可以提供
[startDate] = "{month: {month}, year: {year}"
到 html 组件标签。也许您可以同时使用它来手动确保年份是当前年份。
ng-bootstrap 已过时。更新到 10.0.0 是我的解决方案。
angular 中日期选择器的弹出窗口在打开时显示错误的年份。然而,从 2011 年 12 月之后的那一年开始改为 2021 年。
我正在使用 Angular 12.2.0 和 Bootstrap 4.3.1。我无法弄清楚如何更改它。可能是兼容性问题?对不起我只能link图片因为“声望点数”:P
Datepicker
日期-picker.component.html
<div class="input-group input-group-sm">
<input class="form-control" name="dp" [(ngModel)]="selectedDate" ngbDatepicker #d="ngbDatepicker" (change)="onDateChange($event.target.value)" (dateSelect)="onDateSelect($event)" [disabled]="isDisabled ? 'disabled' : null">
<div class="input-group-append" *ngIf="!isDisabled">
<button class="btn btn-input calendar fa fa-calendar" (click)="d.toggle()" type="button"></button>
</div>
</div>
日期-picker.component.ts
import { Component, OnInit, ViewEncapsulation, forwardRef, Injectable, Output, EventEmitter } from '@angular/core';
import { NgbDateParser } from '../../ngb-date-parser';
import { NgbDateParserFormatter, NgbDatepickerI18n, NgbDateStruct } from '@ng-bootstrap/ng-bootstrap';
import { ControlValueAccessor, NG_VALUE_ACCESSOR, } from '@angular/forms';
const I18N_VALUES = {
'it-IT': {
weekdays: ['Lu', 'Ma', 'Me', 'Go', 'Ve', 'Sa', 'Do'],
months: ['Gen', 'Feb', 'Mar', 'Apr', 'Mag', 'Giu', 'Lug', 'Ago', 'Set', 'Ott', 'Nov', 'Dic'],
},
'de-DE': {
weekdays: ['Mo', 'Di', 'Mi', 'Do', 'Fr', 'Sa', 'So'],
months: ['Jan', 'Feb', 'Mar', 'Apr', 'Mai', 'Jun', 'Jul', 'Aug', 'Sep', 'Okt', 'Nov', 'Dez'],
},
'en-US': {
weekdays: ['Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa', 'Su'],
months: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
},
'en-UK': {
weekdays: ['Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa', 'Su'],
months: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
}
};
@Injectable()
export class I18n {
language = localStorage.getItem('locale');
}
// Define custom service providing the months and weekdays translations
@Injectable()
export class CustomDatepickerI18n extends NgbDatepickerI18n {
constructor(private i18n: I18n) {
super();
}
getWeekdayShortName(weekday: number): string {
return I18N_VALUES[this.i18n.language].weekdays[weekday - 1];
}
getMonthShortName(month: number): string {
return I18N_VALUES[this.i18n.language].months[month - 1];
}
getMonthFullName(month: number): string {
return this.getMonthShortName(month);
}
getDayAriaLabel(date: NgbDateStruct): string {
return `${date.day}-${date.month}-${date.year}`;
}
}
export const DATEPICKER_VALUE_ACCESSOR = {
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => DatePickerComponent),
multi: true
};
@Component({
selector: 'app-date-picker',
templateUrl: './date-picker.component.html',
styleUrls: ['./date-picker.component.scss'],
providers: [DATEPICKER_VALUE_ACCESSOR, {provide: NgbDateParserFormatter, useClass: NgbDateParser},
I18n, {provide: NgbDatepickerI18n, useClass: CustomDatepickerI18n}]
})
export class DatePickerComponent implements ControlValueAccessor {
selectedDate: any;
isDisabled = false;
@Output() dateChange = new EventEmitter<any>();
constructor() {}
// Function to call when the date changes.
onChange = (date?: Date) => {
};
// Function to call when the date picker is touched
onTouched = () => {};
writeValue(value: Date) {
if (!value) {
this.selectedDate = undefined;
return;
}
value = new Date(value);
this.selectedDate = {
year: value.getFullYear(),
month: value.getMonth()+1,
day: value.getDate()
}
}
registerOnChange(fn: (date: Date) => void): void {
this.onChange = fn;
}
// Allows Angular to register a function to call when the input has been touched.
// Save the function as a property to call later here.
registerOnTouched(fn: () => void): void {
this.onTouched = fn;
}
// Allows Angular to disable the input.
setDisabledState(isDisabled: boolean): void {
this.isDisabled = isDisabled;
}
// Write change back to parent
onDateChange(value: string) {
const dateString = value.split('.');
if(dateString.length == 3) {
const date: Date = new Date(+dateString[2], +dateString[1]-1, +dateString[0]);
this.onChange(date);
}
if (value == null || value == '') {
this.onChange(null);
}
}
// Write change back to parent
onDateSelect(value: any) {
this.onChange(new Date(value.year, value.month - 1, value.day));
this.dateChange.emit(value);
}
}
不幸的是,我不太确定为什么默认为 2011 年。
但是,在提供更好的答案之前,根据 ngb-datepicker 文档(https://ng-bootstrap.github.io/#/components/datepicker/overview,标题为内容模板的部分),您可以提供
[startDate] = "{month: {month}, year: {year}"
到 html 组件标签。也许您可以同时使用它来手动确保年份是当前年份。
ng-bootstrap 已过时。更新到 10.0.0 是我的解决方案。