Реализовать привязку переменных в mat-datepicker

Описание


Я пытаюсь обернуть MatDatePicker в пользовательском компоненте под названием MyDatePicker так что я могу использовать его в HTML, как показано ниже.

вопрос


dateVariable всегда неопределен и кажется, что двухстороннее связывание, которое я реализовал ниже, не работает. Как только пользователь выбирает новую дату из средства выбора, вызывается установщик. Однако новое значение не привязано к dateVariable,

Вопросов


  • Как я могу реализовать двустороннюю привязку между моим пользовательским средством выбора даты и переменной?
  • Как можно реализовать одностороннюю привязку (из выбора даты -> переменная)?

Реализация


HTML-файл:

<my-datepicker [(selectedDate)]="dateVariable" placeholder="some text"></my-datepicker>

<button (click)="btnClick()">Show Selected Date</button>

Файл TS:

//...

    dateVariable: string;       

    btnClick() {

      console.log('selected date:', this.dateVariable);
   }
//...

MyDatepicker.component.ts

export class MyDatepickerComponent {

    dateValue: string;
    @Input() placeholder: string;

    @Output() dateChange: EventEmitter<string> = new EventEmitter<string>();

    @Input()
    get selectedDate() {
        console.log('getter');
        return this.dateValue;
    }
    set selectedDate(val) {
        console.log('setter');
        this.dateValue = val;
        this.dateChange.emit(this.dateValue);
    }

    pickerEvent(event: MatDatepickerInputEvent<Date>) {
        this.selectedDate = event.value.toISOString();
    }
}

MyDatepicker.component.html:

<mat-form-field>
        <input matInput [matDatepicker]='pickerDate' placeholder='{{placeholder}}' (dateInput)="pickerEvent($event)">
        <mat-datepicker-toggle matSuffix [for]='pickerDate'></mat-datepicker-toggle>
        <mat-datepicker #pickerDate></mat-datepicker>
</mat-form-field>

2 ответа

Решение

Как уже говорилось: для двусторонней привязки [()] (синтаксис банан в коробке) мы должны написать @Input с соответствующим @Output любить:

@Input() selectedDate: Date;

@Output() selectedDateChange: EventEmitter<Date> = new EventEmitter<Date>();

Это можно использовать с привязкой к входу и отдельной привязкой к выходу:

<my-datepicker [selectedDate]="dateVariable" (selectedDateChange)="dateVariable = $event" placeholder="some text"></my-datepicker>

Или с небольшим синтаксическим сахаром, предоставленным Angular с синтаксисом банан в коробке:

<my-datepicker [(selectedDate)]="dateVariable" placeholder="some text"></my-datepicker>

Примечания в сторону:

1) Я думаю, вам нужно связать matInput с фактическим Date ценность также

<mat-form-field>
        <input matInput [matDatepicker]='pickerDate' [value]="selectedDate" placeholder='{{placeholder}}' (dateInput)="pickerEvent($event)">
        <mat-datepicker-toggle matSuffix [for]='pickerDate'></mat-datepicker-toggle>
        <mat-datepicker #pickerDate></mat-datepicker>
</mat-form-field>

2) Если вы хотите использовать my-datepicker внутри угловой формы вам нужно реализовать ControlValueAccessor интерфейс

3) Если единственная причина, по которой вы пишете этот пользовательский компонент, заключается в том, что вы хотите использовать строку даты ISO в качестве входных данных, я бы предложил обрабатывать это преобразование на уровне API / Service, а не в компоненте.

Для двусторонней привязки к работе, Output() должен быть назван так же, как Input() с суффиксом Change, Поэтому измените свой код как таковой:

@Output() selectedDateChange: EventEmitter<string> = new EventEmitter<string>();

и то же самое в сеттере:

set selectedDate(val) {
    console.log('setter');
    this.dateValue = val;
    this.selectedDateChange.emit(this.dateValue);
}
Другие вопросы по тегам