Angular表单中仅选择年月的日期选择器实现及年月值提取至.ts文件的方法问询
嘿,这个需求我之前做项目的时候刚好碰到过,其实有两种简便的实现方式,一种是用Angular Material的Datepicker(如果你的项目已经在用Material组件库的话),另一种是直接用原生HTML的input控件,都能快速搞定,下面给你详细拆解:
方法一:使用Angular Material Datepicker(推荐用于Material项目)
如果你的项目已经引入了Angular Material,那可以通过配置Datepicker的视图模式来实现仅选年月的效果,还能保持UI风格统一:
模板代码(.html)
<mat-form-field appearance="fill"> <mat-label>选择年月</mat-label> <!-- 绑定ngModel来同步选中值,dateChange事件监听选择变化 --> <input matInput [matDatepicker]="picker" [(ngModel)]="selectedDate" (dateChange)="handleDateSelect($event)" [matDatepickerFilter]="restrictToMonthYear" > <mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle> <!-- 设置startView为multi-year,这样打开时先选年份,再选月份 --> <mat-datepicker #picker startView="multi-year" (yearSelected)="onYearSelected($event)" (monthSelected)="onMonthSelected($event, picker)" ></mat-datepicker> </mat-form-field>
组件代码(.ts)
import { Component } from '@angular/core'; import { MatDatepickerInputEvent, MatDatepicker } from '@angular/material/datepicker'; @Component({ selector: 'app-month-year-picker', templateUrl: './month-year-picker.component.html', styleUrls: ['./month-year-picker.component.css'] }) export class MonthYearPickerComponent { selectedDate: Date = new Date(); selectedYear!: number; selectedMonth!: number; // 注意:原生Date的月份是0开始的,后续需要+1得到实际月份 // 过滤掉具体日期的选择(可选,确保用户只能选到月份层级) restrictToMonthYear = (date: Date | null): boolean => { // 这里可以自定义日期范围,比如只允许选当前及之前的年月 const today = new Date(); return date ? date <= today : false; }; // 处理年份选中事件 onYearSelected(normalizedYear: Date) { const currentValue = this.selectedDate; currentValue.setFullYear(normalizedYear.getFullYear()); this.selectedDate = new Date(currentValue); } // 处理月份选中事件,选完后关闭日期选择器 onMonthSelected(normalizedMonth: Date, datepicker: MatDatepicker<Date>) { const currentValue = this.selectedDate; currentValue.setMonth(normalizedMonth.getMonth()); this.selectedDate = new Date(currentValue); datepicker.close(); } // 提取选中的年份和月份 handleDateSelect(event: MatDatepickerInputEvent<Date>) { if (event.value) { this.selectedYear = event.value.getFullYear(); this.selectedMonth = event.value.getMonth() + 1; // +1转换为1-12的实际月份 console.log('选中的年份:', this.selectedYear, '选中的月份:', this.selectedMonth); // 在这里添加你的业务逻辑处理 } } }
方法二:使用原生HTML input type="month"(最简方案)
如果你的项目不需要Material的UI风格,原生HTML的input[type="month"]是最省事的,浏览器原生支持,不用额外依赖:
模板代码(.html)
<label>选择年月</label> <input type="month" [(ngModel)]="selectedMonthYear" (change)="handleMonthYearSelect($event)" >
组件代码(.ts)
import { Component } from '@angular/core'; @Component({ selector: 'app-native-month-picker', templateUrl: './native-month-picker.component.html', styleUrls: ['./native-month-picker.component.css'] }) export class NativeMonthPickerComponent { selectedMonthYear!: string; // 格式为YYYY-MM selectedYear!: number; selectedMonth!: number; handleMonthYearSelect(event: Event) { const inputValue = (event.target as HTMLInputElement).value; if (inputValue) { // 拆分字符串得到年份和月份 const [yearStr, monthStr] = inputValue.split('-'); this.selectedYear = parseInt(yearStr, 10); this.selectedMonth = parseInt(monthStr, 10); console.log('选中的年份:', this.selectedYear, '选中的月份:', this.selectedMonth); // 在这里处理你的业务逻辑 } } }
关键注意点
- 用Material方案时,记得确保已经在项目中导入了
MatDatepickerModule和MatNativeDateModule(或自定义日期适配器) - 原生
input[type="month"]的兼容性很好,现代浏览器都支持,返回的格式固定为YYYY-MM,拆分起来很方便 - 提取月份时,Material方案的Date对象是0索引的(0=1月,11=12月),需要加1转换为实际月份;原生方案直接得到的是1-12的数值,不用转换
内容的提问来源于stack exchange,提问作者Chathura Jayawardhane




