将类型为 datetime-local 的输入绑定到 Angular 中的日期 属性 2
Bind an input with type datetime-local to a Date property in Angular 2
可以将日期类型的组件 属性 绑定到类型设置为 datetime-local
的 HTML5 输入?
在我的组件中我有一个属性:
public filterDateFrom: Date;
在我的模板中,我将输入定义为:
<input type="datetime-local" [(ngModel)]="filterDateFrom" />
但是绑定不起作用。
您可以使用以下格式绑定到日期:yyyy-MM-ddTHH:mm
,您也可以从 date.toISOString().slice(0,16)
获取(切片删除分钟后的时间部分)。
@Component({
selector: 'app',
template: `<input type="datetime-local" [value]="date"
(change)="date=$event.target.value" /> {{date}}`
})
export class AppComponent {
date: string;
constructor() {
this.date = new Date().toISOString().slice(0, 16);
}
}
请记住,date.toISOString()
将 return 与当地时间的日期偏移。也可以自己构造日期字符串:
private toDateString(date: Date): string {
return (date.getFullYear().toString() + '-'
+ ("0" + (date.getMonth() + 1)).slice(-2) + '-'
+ ("0" + (date.getDate())).slice(-2))
+ 'T' + date.toTimeString().slice(0,5);
}
如果您希望能够将 select 绑定到 Date
模型,您可以使用它来构建自定义日期组件:
@Component({
selector: 'my-date',
events: ['dateChange'],
template: `<input type="datetime-local" [value] = "_date"
(change) = "onDateChange($event.target.value)" />`
})
export class MyDate{
private _date: string;
@Input() set date(d: Date) {
this._date = this.toDateString(d);
}
@Output() dateChange: EventEmitter<Date>;
constructor() {
this.date = new Date();
this.dateChange = new EventEmitter();
}
private toDateString(date: Date): string {
return (date.getFullYear().toString() + '-'
+ ("0" + (date.getMonth() + 1)).slice(-2) + '-'
+ ("0" + (date.getDate())).slice(-2))
+ 'T' + date.toTimeString().slice(0,5);
}
private parseDateString(date:string): Date {
date = date.replace('T','-');
var parts = date.split('-');
var timeParts = parts[3].split(':');
// new Date(year, month [, day [, hours[, minutes[, seconds[, ms]]]]])
return new Date(parts[0], parts[1]-1, parts[2], timeParts[0], timeParts[1]); // Note: months are 0-based
}
private onDateChange(value: string): void {
if (value != this._date) {
var parsedDate = this.parseDateString(value);
// check if date is valid first
if (parsedDate.getTime() != NaN) {
this._date = value;
this.dateChange.emit(parsedDate);
}
}
}
}
您的组件的用户将绑定到具有 two-way 模型绑定的 Date
模型:
@Component({
selector: 'my-app',
directives: [MyDate],
template: '<my-date [(date)]="date"></my-date> {{date}}'
})
export class AppComponent {
@Input() date: Date;
constructor() {
this.date = new Date();
}
}
或者如果你想避免自定义标签,将组件重写为指令:
<input type="datetime-local" [(date)]="date" />
我也在研究这个问题,并开始沿着这个示例之路前进。但是,您可以在 [date,datetime,datetime-local] 类型的输入上使用 [(ngModel)]。关键是匹配控件期望的预期格式。在这种情况下,它期望 this format. Which also means the type that you bind to the control needs to be a string. I have provided an example plunker,它演示了如何使用 [(ngModel)].
import { Component } from 'angular2/core';
@Component({
selector: 'my-app',
template: `
<form>
<input type="datetime-local" [(ngModel)]="dateTimeLocal"><br />
{{dateTimeLocal}}
</form>
`
})
export class AppComponent {
private _dateTimeLocal: Date;
constructor() {
this._dateTimeLocal = new Date();
}
private parseDateToStringWithFormat(date: Date): string {
let result: string;
let dd = date.getDate().toString();
let mm = (date.getMonth() + 1).toString();
let hh = date.getHours().toString();
let min = date.getMinutes().toString();
dd = dd.length === 2 ? dd : "0" + dd;
mm = mm.length === 2 ? mm : "0" + mm;
hh = hh.length === 2 ? hh : "0" + hh;
min = min.length === 2 ? min : "0" + min;
result = [date.getFullYear(), '-', mm, '-', dd, 'T', hh, ':', min].join('');
return result;
}
public set dateTimeLocal(v: string) {
let actualParsedDate = v ? new Date(v) : new Date();
let normalizedParsedDate = new Date(actualParsedDate.getTime() + (actualParsedDate.getTimezoneOffset() * 60000));
this._dateTimeLocal = normalizedParsedDate;
}
public get dateTimeLocal(): string {
return this.parseDateToStringWithFormat(this._dateTimeLocal);
}
}
现在 Spring 2017 年,DatePipe
已发售 OOTB。您可以通过为管道指定格式参数来实现(单向)绑定。例如:
<input type="datetime-local" [ngModel]="filterDateFrom | date:'yyyy-MM-ddTHH:mm'" />
需要注意的是,您不能通过这种技术使用双向绑定,您必须使用一种方式绑定数据管道,然后管理 DOM 来建模更改事件以处理客户端更改控件(除非我遗漏了什么!),但这样看起来更清晰。
更新
看来我确实漏掉了什么!
在上面添加 ngModelChange
应该提供 DOM --> 双向绑定过程的模型端:
<input type="datetime-local"
[ngModel]="filterDateFrom | date:'yyyy-MM-ddTHH:mm'"
(ngModelChange)="filterDateFrom = $event" />
受@ne1410s 回答的启发,我结束了一些非常相似但没有丢失日期类型的事情。
我使用管道声明 ngModel
并调用方法 dateChanged
只是为了 return 转换 ts
中的新日期。
html代码:
<input type="datetime-local" [ngModel]="filterDateFrom | date:'yyyy-MM-ddTHH:mm'" (ngModelChange)="filterDateFrom = dateChanged($event)"/>
ts代码:
dateChanged(eventDate: string): Date | null {
return !!eventDate ? new Date(eventDate) : null;
}
可以将日期类型的组件 属性 绑定到类型设置为 datetime-local
的 HTML5 输入?
在我的组件中我有一个属性:
public filterDateFrom: Date;
在我的模板中,我将输入定义为:
<input type="datetime-local" [(ngModel)]="filterDateFrom" />
但是绑定不起作用。
您可以使用以下格式绑定到日期:yyyy-MM-ddTHH:mm
,您也可以从 date.toISOString().slice(0,16)
获取(切片删除分钟后的时间部分)。
@Component({
selector: 'app',
template: `<input type="datetime-local" [value]="date"
(change)="date=$event.target.value" /> {{date}}`
})
export class AppComponent {
date: string;
constructor() {
this.date = new Date().toISOString().slice(0, 16);
}
}
请记住,date.toISOString()
将 return 与当地时间的日期偏移。也可以自己构造日期字符串:
private toDateString(date: Date): string {
return (date.getFullYear().toString() + '-'
+ ("0" + (date.getMonth() + 1)).slice(-2) + '-'
+ ("0" + (date.getDate())).slice(-2))
+ 'T' + date.toTimeString().slice(0,5);
}
如果您希望能够将 select 绑定到 Date
模型,您可以使用它来构建自定义日期组件:
@Component({
selector: 'my-date',
events: ['dateChange'],
template: `<input type="datetime-local" [value] = "_date"
(change) = "onDateChange($event.target.value)" />`
})
export class MyDate{
private _date: string;
@Input() set date(d: Date) {
this._date = this.toDateString(d);
}
@Output() dateChange: EventEmitter<Date>;
constructor() {
this.date = new Date();
this.dateChange = new EventEmitter();
}
private toDateString(date: Date): string {
return (date.getFullYear().toString() + '-'
+ ("0" + (date.getMonth() + 1)).slice(-2) + '-'
+ ("0" + (date.getDate())).slice(-2))
+ 'T' + date.toTimeString().slice(0,5);
}
private parseDateString(date:string): Date {
date = date.replace('T','-');
var parts = date.split('-');
var timeParts = parts[3].split(':');
// new Date(year, month [, day [, hours[, minutes[, seconds[, ms]]]]])
return new Date(parts[0], parts[1]-1, parts[2], timeParts[0], timeParts[1]); // Note: months are 0-based
}
private onDateChange(value: string): void {
if (value != this._date) {
var parsedDate = this.parseDateString(value);
// check if date is valid first
if (parsedDate.getTime() != NaN) {
this._date = value;
this.dateChange.emit(parsedDate);
}
}
}
}
您的组件的用户将绑定到具有 two-way 模型绑定的 Date
模型:
@Component({
selector: 'my-app',
directives: [MyDate],
template: '<my-date [(date)]="date"></my-date> {{date}}'
})
export class AppComponent {
@Input() date: Date;
constructor() {
this.date = new Date();
}
}
或者如果你想避免自定义标签,将组件重写为指令:
<input type="datetime-local" [(date)]="date" />
我也在研究这个问题,并开始沿着这个示例之路前进。但是,您可以在 [date,datetime,datetime-local] 类型的输入上使用 [(ngModel)]。关键是匹配控件期望的预期格式。在这种情况下,它期望 this format. Which also means the type that you bind to the control needs to be a string. I have provided an example plunker,它演示了如何使用 [(ngModel)].
import { Component } from 'angular2/core';
@Component({
selector: 'my-app',
template: `
<form>
<input type="datetime-local" [(ngModel)]="dateTimeLocal"><br />
{{dateTimeLocal}}
</form>
`
})
export class AppComponent {
private _dateTimeLocal: Date;
constructor() {
this._dateTimeLocal = new Date();
}
private parseDateToStringWithFormat(date: Date): string {
let result: string;
let dd = date.getDate().toString();
let mm = (date.getMonth() + 1).toString();
let hh = date.getHours().toString();
let min = date.getMinutes().toString();
dd = dd.length === 2 ? dd : "0" + dd;
mm = mm.length === 2 ? mm : "0" + mm;
hh = hh.length === 2 ? hh : "0" + hh;
min = min.length === 2 ? min : "0" + min;
result = [date.getFullYear(), '-', mm, '-', dd, 'T', hh, ':', min].join('');
return result;
}
public set dateTimeLocal(v: string) {
let actualParsedDate = v ? new Date(v) : new Date();
let normalizedParsedDate = new Date(actualParsedDate.getTime() + (actualParsedDate.getTimezoneOffset() * 60000));
this._dateTimeLocal = normalizedParsedDate;
}
public get dateTimeLocal(): string {
return this.parseDateToStringWithFormat(this._dateTimeLocal);
}
}
现在 Spring 2017 年,DatePipe
已发售 OOTB。您可以通过为管道指定格式参数来实现(单向)绑定。例如:
<input type="datetime-local" [ngModel]="filterDateFrom | date:'yyyy-MM-ddTHH:mm'" />
需要注意的是,您不能通过这种技术使用双向绑定,您必须使用一种方式绑定数据管道,然后管理 DOM 来建模更改事件以处理客户端更改控件(除非我遗漏了什么!),但这样看起来更清晰。
更新
看来我确实漏掉了什么!
在上面添加 ngModelChange
应该提供 DOM --> 双向绑定过程的模型端:
<input type="datetime-local"
[ngModel]="filterDateFrom | date:'yyyy-MM-ddTHH:mm'"
(ngModelChange)="filterDateFrom = $event" />
受@ne1410s 回答的启发,我结束了一些非常相似但没有丢失日期类型的事情。
我使用管道声明 ngModel
并调用方法 dateChanged
只是为了 return 转换 ts
中的新日期。
html代码:
<input type="datetime-local" [ngModel]="filterDateFrom | date:'yyyy-MM-ddTHH:mm'" (ngModelChange)="filterDateFrom = dateChanged($event)"/>
ts代码:
dateChanged(eventDate: string): Date | null {
return !!eventDate ? new Date(eventDate) : null;
}