У меня есть компонент, который использует ввод с типом date и bsDatepicker и ввод с выпадающим списком.
Когда компонент загружается, у меня есть предопределенные значения на входе и в раскрывающемся списке
Вот HTML
<div class="form-group">
<div class="form-row">
<div class="form-group col-md-3">
<label>{{ l('StartDate') }}</label>
<utc-datepicker name="TenancyStartDate" [(ngModel)]="startDate"></utc-datepicker>
</div>
<div class="col-md-6">
<label>{{ l('Duration') }}</label>
<div class="form-row">
<div class="form-group col-md-4">
<input
type="text"
[readonly]="durationReadonly"
class="form-control"
[(ngModel)]="durationNumber"
(ngModelChange)="setEndDate()"
name="durationNumber"
/>
</div>
<div class="form-group col-md-6">
<p-dropdown
[options]="contractTimespanUnitOptions"
name="ContractTimespanUnit"
[(ngModel)]="contractTermUnit"
(ngModelChange)="setEndDate()"
[autoWidth]="false"
styleClass="h-100"
[readonly]="durationReadonly"
></p-dropdown>
</div>
</div>
</div>
</div>
</div>
<div class="form-group">
<div class="form-row">
<div class="form-group col-md-3">
<label>{{ l('EndDate') }}</label>
<utc-datepicker
name="TenancyEndDate"
[(ngModel)]="endDate"
(ngModelChange)="updateReminderDate()"
></utc-datepicker>
<i class="glyphicon glyphicon-calendar col-sm-pull-2"></i>
</div>
<div class="form-group col-md-3">
<p class="totalDuration">
<b>{{ l('TotalDuration') }} {{ totalDuration }}</b>
</p>
</div>
</div>
</div>
Здесь часть кода компонента, относящаяся к этим входам
ngOnInit(): void {
this.startDate = moment();
this.durationNumber = 6;
this.contractTermUnit = 1;
this._tenancyService
.getContractTypesDropdownValues()
.subscribe(result => (this.contractTypesOptions = result.items.map(c => ({ label: c.name, value: c.id }))));
this.setEndDate();
}
//Setting end date when we change duration number or duration dropdown
setEndDate(): void {
if (this.contractTermUnit === 0) {
this.endDate = moment(this.startDate).add(this.durationNumber, 'W');
}
if (this.contractTermUnit === 1) {
this.endDate = moment(this.startDate).add(this.durationNumber, 'M');
}
if (this.contractTermUnit === 2) {
this.endDate = moment(this.startDate).add(this.durationNumber, 'Y');
}
this.updateReminderDate();
this.setTotalDuration();
}
Вот код <utc-datepicker>
import { Component, Input, Output, EventEmitter } from '@angular/core';
import { NG_VALUE_ACCESSOR, ControlValueAccessor } from '@angular/forms';
import { Moment } from 'moment';
import * as moment from 'moment';
@Component({
selector: 'utc-datepicker',
template: `
<div class="input-group mb-4">
<div class="input-group-prepend">
<span class="input-group-text"><i class="far fa-calendar-alt"></i></span>
</div>
<input
#date="ngModel"
[readonly]="notEditable"
[disabled]="notEditable"
type="datetime"
class="form-control"
bsDatepicker
[(ngModel)]="value"
(change)="valueChanged()"
autocomplete="off"
/>
</div>
`,
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: UtcDatepickerComponent,
multi: true,
},
],
})
export class UtcDatepickerComponent implements ControlValueAccessor {
@Output() readonly: EventEmitter<any> = new EventEmitter<any>();
@Input() notEditable: boolean;
@Input() isRequired: boolean;
innerValue: Date;
get value(): Date {
return this.innerValue ? this.innerValue : undefined;
}
set value(value: Date) {
if (value !== this.innerValue) {
this.innerValue = value;
this.onChangeCallback(this.localToUtc(value));
}
}
onBlur(): void {
this.onTouchedCallback();
}
writeValue(value: any): void {
if (value !== this.innerValue) {
this.innerValue = value;
}
}
registerOnChange(fn: any): void {
this.onChangeCallback = fn;
}
registerOnTouched(fn: any): void {
this.onTouchedCallback = fn;
}
private onTouchedCallback: () => void = () => {};
private onChangeCallback: (_: any) => void = () => {};
private localToUtc(date: Date): Moment {
if (!date) {
return null;
}
const result = new Date(
Date.UTC(
date.getUTCFullYear(),
date.getMonth(),
date.getDate(),
date.getHours(),
date.getMinutes(),
date.getSeconds()
)
);
return moment(result);
}
valueChanged(): void {
console.log('test');
this.readonly.emit({ readonly: true });
}
}
Задача Для этого
Я выбираю длительность или дату окончания
При выборе длительности автоматически заполняется дата окончания
Перезапись даты окончания отключит поле длительности
Я пытаюсь запустить функцию для события (change)
, установить параметр Output и передать его родительскому компоненту. И используйте в разделе продолжительности. Но (change)
не работает.
(ngModelChange)
не годится для использования, потому что модель изменяется при инициализации и ломает логи c
Как мне этого добиться?