Это может быть одна из самых неприятных проблем, с которыми я справился за последнее время. Даты и, в частности, NgbDatepicker, в целом, немного неудобны для Angular.
Я использую NgbDatepicker против реактивных форм в Angular 8, и суть Моя проблема в том, что я могу установить начальное значение элемента управления датой, но это начальное значение не отображается (визуально) в форме. Я могу зарегистрировать свою форму на консоли и увидеть, что значение устанавливается, но само поле формы не обновляется. Если я выберу дату из самого средства выбора, мой выбор отобразится в поле формы. Я думал, что это будет так же просто, как установить свойство [startDate]
ввода ngbDatepicker, но, видимо, нет. Я пробовал много разных вариантов этого; вот где все стоит по коду:
My HTML:
<input #licenseExpiration="ngbDatepicker"
class="form-control"
fromControlName="licenseExpiration"
[startDate]="startDate"
ngbDatepicker />
<button class="btn btn-info zero-spacing pt-1 pr-1 pl-1"
(click)="licenseExpiration.toggle()"
type="button">
Соответствующие биты моего компонента:
@Component({
selector: 'app-cert',
templateUrl: './cert.component.html',
providers: [
{ provide: NgbDateParserFormatter, useClass: CustomDateParserFormatter }
]
})
export class CertComponent implements OnInit {
certForm: CertForm = new CertForm();
constructor(
public readonly formatter: CustomDateParserFormatter) { }
ngOnInit() {
this.certForm.setModel(...modelObjectFromOtherService...);
}
get startDate() {
return { year: 2020, month: 6, day: 13 };
}
}
Выше HTML находится в группе formGroup, которая является spe c 'd этим типом CertForm. Эта форма содержит элемент управления для даты и выглядит (частично) следующим образом:
export class CertForm extends FormGroup {
public dateParser: CustomDateParserFormatter;
constructor(
cert: ICertModel = new CertModel()) {
super({
..
licenseExpiration: new FormControl("", Validators.required),
..
});
}
setModel(cert: ICertModel) {
this.patchValue({
licenseExpiration
});
}
getModel(): ICertModel {
const cert = new CertModel();
...
cert.licenseExpiration = this.get("licenseExpiration").value;
...
return cert;
}
}
Оттуда у меня есть настраиваемый парсер / форматировщик, и он выглядит так же, как тот, который является spe c 'd на страницах примеров NGB:
@Injectable({
providedIn: "root"
})
export class CustomDateParserFormatter extends NgbDateParserFormatter {
readonly DELIMITER = '/';
parse(value: string): NgbDateStruct | null {
if (value) {
let date = value.split(this.DELIMITER);
return {
day: parseInt(date[0], 10),
month: parseInt(date[1], 10),
year: parseInt(date[2], 10)
};
}
return null;
}
format(date: NgbDateStruct | null): string {
return date ? date.month + this.DELIMITER + date.day + this.DELIMITER + date.year : '';
}
}
И, опять же, похоже, это просто не позволяет мне инициировать это поле даты с видимым начальным значением. Как видите, сейчас я просто жестко кодирую возвращаемое значение для этой даты начала. И эта дата действительно устанавливается правильно - когда вы открываете средство выбора, это дата, на которую он приземляется, но на самом деле он не отображается в поле отображения, когда вы попадаете на страницу. Это просто пусто, пока вы не выберете значение.
Я пробовал так много различных комбинаций идей, но ничего не работает. Это невероятно расстраивает. Я вижу, что варианты / фрагменты этого вопроса уже существуют, но я не могу найти примеров вопроса, который задается именно с этой комбинацией технологий. При использовании NgbDatepicker большинство людей полагаются на шаблонные, а не на реактивные формы.