~
// -------------------------自定义时间查询zjy-----------------------------------------------------------------------------------
//是否展示自定义时间框
showCustomTime: boolean = false;
//获得日期范围的工具类
utilDate: UtilDate = new UtilDate();
//自定义的日期开始||结束值
startValue: Date | null = null;
endValue: Date | null = null;
customTime($event) {
if ($event == 'timeByMySelf') {
this.showCustomTime = true;
this.searchAll.startPublishDate = '';
this.searchAll.endPublishDate = '';
// this.postsearch.emit(this.searchAll);
} else if ($event == 'day') {
this.getDayDate()
this.showCustomTime = false;
this.startValue = null;
this.endValue = null;
} else if ($event == 'week') {
this.getWeekDate()
this.startValue = null;
this.endValue = null;
this.showCustomTime = false;
} else if ($event == 'month') {
this.getMonthDate()
this.startValue = null;
this.endValue = null;
this.showCustomTime = false;
}
}
//查询本日的产品列表,通过获取本日的时间范围
getDayDate() {
let search: TableSearch = new TableSearch();
search.startPublishDate = this.utilDate.getDayAndWeek('day').begin;
search.endPublishDate = search.startPublishDate;
this.searchAll.startPublishDate = search.startPublishDate;
this.searchAll.endPublishDate = search.endPublishDate;
this.postsearch.emit(search);
console.log('day', search);
}
//查询本周的产品列表,通过获取本日的时间范围
getWeekDate() {
let search: TableSearch = new TableSearch();
search.startPublishDate = this.utilDate.getDayAndWeek('week').begin;
search.endPublishDate = this.utilDate.getDayAndWeek('week').over;
this.searchAll.startPublishDate = search.startPublishDate;
this.searchAll.endPublishDate = search.endPublishDate;
this.postsearch.emit(search);
console.log('week', search);
}
//查询本月的产品列表,通过获取本日的时间范围
getMonthDate() {
let search: TableSearch = new TableSearch();
search.startPublishDate = this.utilDate.getMonth().begin;
search.endPublishDate = this.utilDate.getMonth().over;
this.searchAll.startPublishDate = search.startPublishDate;
this.searchAll.endPublishDate = search.endPublishDate;
this.postsearch.emit(search);
console.log('month', search);
}
disabledStartDate = (startValue: Date): boolean => {
if (!startValue || !this.endValue) {
return false;
}
return startValue.getTime() > this.endValue.getTime();
};
disabledEndDate = (endValue: Date): boolean => {
if (!endValue || !this.startValue) {
return false;
}
return endValue.getTime() <= this.startValue.getTime();
};
onStartChange(date: Date): void {
this.startValue = date;
if (this.endValue == null && date != null) {
this.endValue = null;
this.selfTimeChange()
}
else if (this.startValue == null && this.endValue == null) {
this.searchAll.startPublishDate = '';
this.searchAll.endPublishDate = '';
this.postsearch.emit(this.searchAll);
} else if (this.startValue == null) {
this.searchAll.startPublishDate = '';
// this.endValue = null;
this.postsearch.emit(this.searchAll);
} else if (this.startValue && this.endValue) {
this.selfTimeChange()
}
}
onEndChange(date: Date): void {
this.endValue = date;
if (this.startValue == null && date != null) {
this.startValue = null;
this.selfTimeChange()
}
else if (this.startValue == null && this.endValue == null) {
this.searchAll.startPublishDate = '';
this.searchAll.endPublishDate = '';
this.postsearch.emit(this.searchAll);
} else if (this.endValue == null) {
this.searchAll.endPublishDate = '';
// this.startValue = null
this.postsearch.emit(this.searchAll);
} else if (this.startValue && this.endValue) {
this.selfTimeChange()
}
}
/**
* 查询自定义时间范围的产品列表数据
*/
selfTimeChange() {
let search: TableSearch = new TableSearch();
if (this.startValue) {
let arr = (this.startValue.toLocaleDateString() + '').split('/')
search.startPublishDate = arr[0] + '-' + arr[1] + '-' + arr[2];
}
if (this.endValue) {
let arr = (this.endValue.toLocaleDateString() + '').split('/')
search.endPublishDate = arr[0] + '-' + arr[1] + '-' + arr[2];
}
if (this.endValue == null) {
search.endPublishDate = ''
}
if (this.startValue == null) {
search.startPublishDate = ''
}
this.searchAll.startPublishDate = search.startPublishDate;
this.searchAll.endPublishDate = search.endPublishDate;
this.postsearch.emit(search);
console.log('timeByself', search);
}
// -----------------------------------------------------------------------------------------------------------------------------
export class UtilDate {
getCurrentDate() {
let date = new Date();
let year = date.getFullYear(); //获取年
let month = date.getMonth() + 1; //获取月
let day = date.getDate(); //获取日
let weekDay = date.getDay(); // 星期
let timesStamp = date.getTime(); //getTime() 方法可返回距 1970 年 1 月 1 日之间的毫秒数。
return {
year,
month,
day,
weekDay,
//没用到
timesStamp
}
}
/**
*
* @param date 传入DayAndWeek(string)和getMonth(object)
* @param separator 可以自定义所匹配的格式 eg:// YYYY-MM-DD 2019-01-10
*/
myformatStr(date, separator?) {
let year;
let month;
let day;
if (typeof date == 'string') {
year = date.split('/')[0];
month = date.split('/')[1];
day = date.split('/')[2];
} else if (typeof date == 'object') {
year = date.year;
month = date.month;
day = date.day;
}
let mStr = month < 10 ? '0' + month : month + '';
let dStr = day < 10 ? '0' + day : day + '';
if (separator) {
return year + separator + mStr + separator + dStr;
}
return year + '-' + mStr + '-' + dStr;
}
getDayAndWeek(type){
let date = new Date();
let pre = 0;
let next = 0;
let startTime = '';
let endTime = '';
let begin;
let over;
switch (type) {
case 'day':
next++;
break;
case 'week':
pre = 1 - date.getDay();
next = 7 - date.getDay() ;
break;
default:
}
startTime = new Date(date.getTime() + 24 * 60 * 60 * 1000 * pre).toLocaleDateString();
endTime = new Date(date.getTime() + 24 * 60 * 60 * 1000 * next).toLocaleDateString();
begin = this.myformatStr(startTime);
over = this.myformatStr(endTime);
return { begin, over };
}
/**
* 获取本月日期范围
*/
getMonth() {
let date = this.getCurrentDate();
let monthStart = {};
let monthEnd = {};
let begin;
let over;
if (date.month == 12) {
monthEnd = { year: date.year + 1, month: date.month + 1, day: 1 };
} else {
monthEnd = { year: date.year, month: date.month + 1, day: 1 };
}
monthStart = { year: date.year, month: date.month, day: 1 };
begin = this.myformatStr(monthStart)
over = this.myformatStr(monthEnd)
return { begin, over }
}
getTimeByMyself(time, id: number) {
let date = this.getCurrentDate();
let selfTimeStart = {};
let selfTimeEnd = {};
let begin;
let over;
let endDay;
let condition;
let cond;
date.year = time.split('/')[0];
date.month = time.split('/')[1];
date.day = time.split('/')[2];
if (id == 2) {
endDay = Number(date.day) + 1
}
selfTimeStart = { year: date.year, month: date.month, day: date.day };
selfTimeEnd = { year: date.year, month: date.month, day: endDay};
condition = { year: date.year, month: date.month, day: endDay - 1};
begin = this.myformatStr(selfTimeStart)
over = this.myformatStr(selfTimeEnd)
cond = this.myformatStr(condition)
return { begin, over,cond }
}
}
桥豆麻袋。。。。这个插件还不对劲,根据要求是要再次点击radio就要清空查询条件的。
So不用能ng-zorro的组件了。大佬写了自定义的组件。(组件是大佬写的=。。=)
自定义插件如下:
ts
import { Component, OnInit, ElementRef, Renderer2, Input, ViewChild, HostListener, Output, EventEmitter, ChangeDetectorRef, forwardRef } from '@angular/core';
import { Subject } from 'rxjs';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
@Component({
selector: '[sl-radio]',
templateUrl: './radio-tpl.component.html',
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => RadioTplComponent),
multi: true
}
],
})
export class RadioTplComponent implements OnInit, ControlValueAccessor {
name: string;
isMultiple: boolean; // 是否支持多选
@Input() isCanCancel: boolean;
@Input() isSelected: boolean;
@Input() isDisabled: boolean;
@Input() slValue: any;
onChange: (_: boolean) => void = () => null;
onTouched: () => void = () => null;
@ViewChild('inputElement', { static: false }) inputElement: ElementRef;
select$ = new Subject<RadioTplComponent>();
touched$ = new Subject<void>();
constructor(
private cdr: ChangeDetectorRef,
private elementRef: ElementRef,
private renderer: Renderer2,
) {
this.renderer.addClass(elementRef.nativeElement, 'sl-radio-wrapper');
}
ngOnInit() {
}
@HostListener('click', ['$event'])
onClick(event: MouseEvent): void {
event.stopPropagation();
event.preventDefault();
if (!this.isDisabled && !this.isSelected) {
this.select$.next(this);
this.isSelected = true;
this.onChange(true);
} else if (!this.isDisabled && this.isSelected && this.isCanCancel) {
this.select$.next(this);
this.isSelected = false;
this.onChange(false);
}
}
markForCheck(): void {
this.cdr.markForCheck();
}
writeValue(value: any): void {
this.isSelected = value;
this.cdr.markForCheck();
}
registerOnChange(fn: any): void {
this.onChange = fn;
}
registerOnTouched(fn: any): void {
this.onTouched = fn;
}
setDisabledState?(isDisabled: boolean): void {
this.isDisabled = isDisabled;
this.cdr.markForCheck();
}
}
通过 ElementRef 我们就可以封装不同平台下视图层中的 native 元素 (在浏览器环境中,native 元素通常是指 DOM 元素),最后借助于 Angular 提供的强大的依赖注入特性,我们就可以轻松地访问到 native 元素。
import { Component, OnInit, Renderer2, ElementRef, ChangeDetectorRef, ContentChildren, QueryList, forwardRef, Input, AfterContentInit, OnDestroy, OnChanges, SimpleChanges } from '@angular/core';
import { RadioTplComponent } from './radio-tpl.component';
import { isNotNil, isString } from '../../utils/convert';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
import { startWith, takeUntil } from 'rxjs/operators';
import { Subject, Subscription, merge } from 'rxjs';
@Component({
selector: 'sl-radio-group',
templateUrl: './radio-group-tpl.component.html',
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => RadioGroupTplComponent),
multi: true
}
],
})
export class RadioGroupTplComponent implements AfterContentInit, ControlValueAccessor, OnDestroy, OnChanges {
@Input() isCanCancel: boolean = false;
@Input() isDisabled: boolean;
@Input() slName: string;
@Input() isMultiple: boolean; // 是否支持多选
@ContentChildren(forwardRef(() => RadioTplComponent), { descendants: true }) radios: QueryList<RadioTplComponent>;
onChange: (_: string) => void = () => null;
onTouched: () => void = () => null;
private value: any;
private destroy$ = new Subject();
private selectSubscription: Subscription;
private touchedSubscription: Subscription;
constructor(private cdr: ChangeDetectorRef, renderer: Renderer2, elementRef: ElementRef) {
renderer.addClass(elementRef.nativeElement, 'sl-radio-group-wrapper');
}
updateChildrenStatus(): void {
if (this.radios) {
Promise.resolve().then(() => {
this.radios.forEach(radio => {
radio.isSelected = radio.slValue == this.value;
radio.isCanCancel = this.isCanCancel;
radio.isMultiple = this.isMultiple;
if (isNotNil(this.isDisabled)) {
radio.isDisabled = this.isDisabled;
}
if (this.slName) {
radio.name = this.slName;
}
radio.markForCheck();
})
})
}
}
ngOnChanges(changes: SimpleChanges): void {
if (changes.isDisabled || changes.slName) {
this.updateChildrenStatus();
}
}
ngOnDestroy(): void {
this.destroy$.next();
this.destroy$.complete();
}
writeValue(value: any): void {
this.value = value;
this.updateChildrenStatus();
this.cdr.markForCheck();
}
registerOnChange(fn: any): void {
this.onChange = fn;
}
registerOnTouched(fn: any): void {
this.onTouched = fn;
}
setDisabledState?(isDisabled: boolean): void {
this.isDisabled = isDisabled;
this.cdr.markForCheck();
}
ngAfterContentInit(): void {
this.radios.changes
.pipe(
startWith(null),
takeUntil(this.destroy$)
).subscribe(() => {
this.updateChildrenStatus();
if (this.selectSubscription) {
this.selectSubscription.unsubscribe();
}
this.selectSubscription = merge(...this.radios.map(radio => radio.select$))
.pipe(takeUntil(this.destroy$))
.subscribe(radio => {
if (this.isMultiple) { // 支持多选
let vals = this.value && isString(this.value) ? this.value.split(',') : [];
let index = vals.findIndex(ele => ele == radio.slValue);
if (index != -1) {
vals.splice(index, 1);
} else {
vals.push(radio.slValue);
}
let val = '';
vals.forEach(ele => {
val += ele + ',';
})
this.value = val ? val.substring(0, val.length - 1) : val;
this.onChange(vals);
} else {
if (this.value !== radio.slValue) {
this.value = radio.slValue;
this.updateChildrenStatus();
this.onChange(this.value);
} else {
if (this.isCanCancel) {
this.value = null;
this.updateChildrenStatus();
this.onChange(this.value);
}
}
}
});
if (this.touchedSubscription) {
this.touchedSubscription.unsubscribe();
}
this.touchedSubscription = merge(...this.radios.map(radio => radio.touched$))
.pipe(takeUntil(this.destroy$))
.subscribe(() => {
Promise.resolve().then(() => this.onTouched());
});
});
}
}
<ng-content></ng-content>
radio组件用到的样式
.sl-radio-wrapper {
box-sizing: border-box;
margin: 0 8px 0 0;
padding: 0;
color: rgba(0, 0, 0, .65);
font-size: 14px;
font-variant: tabular-nums;
line-height: 1.5;
list-style: none;
font-feature-settings: 'tnum';
position: relative;
display: inline-block;
white-space: nowrap;
cursor: pointer;
}
.sl-radio {
width: 16px;
height: 16px;
box-sizing: border-box;
margin: 0;
padding: 0;
color: rgba(0, 0, 0, .65);
font-size: 14px;
font-variant: tabular-nums;
list-style: none;
font-feature-settings: 'tnum';
position: relative;
display: inline-block;
line-height: 1;
white-space: nowrap;
vertical-align: sub;
outline: 0;
cursor: pointer;
.sl-radio-input {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
cursor: pointer;
opacity: 0;
}
.sl-radio-inner {
position: absolute;
top: -1px;
}
}
.sl-radio-content {
padding-right: 8px;
padding-left: 8px;
}
关于radio-group组件的各种组合
单个 radio状态
可取消选中
不可取消选中
多个radio互斥,可选中1个,可1个不选
多个radio互斥,要么不选,要么选中1个
多个radio 不互斥,可多选,也可不选
清除