前言
在项目中需要设置用户不能选择今天以前的日期,但是每天的日期是会变的,所以需要动态地设置截至日期。
<input>的max和min属性
max,min 属性规定 <input> 元素的最大值和最小值,也就是可以依次来设置截止日期。
// 选择最大日期为2022年2月20
1 <input type="date" max="2022-02-20">
// 选择最小日期为2022年2月18
2 <input type="date" min="2022-02-18">
// 日期为两者中间
3 <input type="date" min="2022-02-18" max="2022-02-20">
所以只要在组件初始化时获取现在的时间戳,转换成yyyy-MM-dd的格式就能实现。
另外注意月份的如果小于10,如果不写前面的0会设置失败。
设置截至日期
首先获取现在的时间戳,angular中可以直接使用new Date().valueOf()获取。
// 获取当前时间戳
const nowDateTime = new Date().valueOf();
获取到时间戳后有以下几种处理方式。
方法一:用angular内置管道
1 <input class="form-control" type="date" id="date"
2 max = "{{nowDateTime | date:'yyyy-MM-dd'}}"
3 [formControl]="formControl" >
使用angular自带的管道直接将时间戳转换成yyyy-MM-dd格式,
方法二:利用document.getElementById
//获取当前时间戳
1 this.nowDateTime = new Date().valueOf();
//将时间戳转换为yyyy-MM-dd格式
2 this.maxTime = this.getTime(this.nowDateTime);
//利用document.getElementById获取到相应的input的标签
3 const inputElement = document.getElementById('date');
//设置最大日期
4 inputElement.setAttribute('max', this.maxTime);
这种方法可以直接在c层设置input的属性,不用在v层手动添加max属性。
但是需要手动将时间戳转换成yyyy-MM-dd格式。可以参考一下转换代码。
/**
* 把时间戳转化为 y-m-r 形式
* @param timeStamp 时间戳
*/
getTime(timeStamp: number): string {
const date = new Date(timeStamp);
const year = date.getFullYear().toString();
const month = date.getMonth() + 1;
const day = date.getDate();
return year + '-' + (month < 10 ? '0' + month : month) + '-' + (day < 10 ? '0' + day : day);
}
方法三: 用[max]或[attr.max]形式添加
在c层获取到yyyy-MM-dd格式的时间maxTime后,也可以手动在input标签这添加[max]或[attr.max]属性。
c层:
//获取当前时间戳
1 this.nowDateTime = new Date().valueOf();
//将时间戳转换为yyyy-MM-dd格式
2 this.maxTime = this.getTime(this.nowDateTime);
v层:
1 <input class="form-control" type="date" id="date"
2 [max] = "maxTime"
3 // 或者 [attr.max] = "maxTime"
4 [formControl]="formControl" >
关于[max]和[attr.max]
这两种绑定都是属性绑定。虽然这两种方式都能使用,但是两种一个翻译为property,一个翻译为attribute。工作的方式也不同。
property绑定:[max] = "maxTime"
attribute绑定:[attr.max] = "maxTime"
property绑定,也就是[max]的形式,只能用于该标签实际存在的属性。input标签必须存在max这个属性。
attribute绑定,也就是[attr.max]的形式。它只是将max属性添加到 DOM元素。只是添加到 DOM 而不是由元素处理。所以任意写一个abcde的名字,如[attr.abcde],也能通过编译。只是没有起到任何作用。
关于[max]和max
可以观察到第一种方法的max没有加中括号,第三种方法的max加了。
1 [max] = "maxTime" √
2 max = "{{nowDateTime | date:'yyyy-MM-dd'}}" √
3 [max] = "'2020-01-22'"
4 max = "{{maxTime}}"
5 [max] = "{max: '2022-01-02'}" //仅为示例
简单来说就是带了中括号表示后面一般习惯要跟变量,如1。
不带中括号的后面一般跟定值,如2。
但是实际上不这么做也可以,如3和4。
不过,只有[ ]的形式后面才可以跟对象,如5,不加中括号会认为后面是字符串。
最终使用效果
子组件添加@input后,父组件就能通过设置[setMaxToday]="true",来控制截止日期为今天。不设置,则功能同以前一样。
<yz-date [formControlName]="keys.date" [setMaxToday]="true"></yz-date>
/**
* 设置最大日期为今天(可选)
*/
@Input()
set setMaxToday(set: boolean) {
if(set){
const nowDateTime = new Date().valueOf();
this.maxTime = this.getTime(nowDateTime);
}
}
题外
吐糟一下这个自带的clear功能。它仅仅是把对应formControl的value值置为空字符串:' ',并没有置为null,这就导致设置的[disabled]="formControl.invalid"通过了。确认按钮能够点击。
后来解决办法是:加上如下第二行,(change)能使input值改变时执行函数
1 <input class="form-control" type="date" id="date"
2 (change)="dateChanged()"
3 [max] = "maxTime"
4 [formControl]="formControl" >
/**
* 当点击clear时,设置formControl为invalid
*/
dateChanged(){
if (!this.formControl.value){
this.formControl.setValue(null);
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。