关于angular自义定radio组合实现学习总结

自己用了ng-zorro的组件去写。
在这里插入图片描述


              
                
                
                
                
                
                  
                  ~
                  
                  
                
              
              
// -------------------------自定义时间查询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 }
    }
}

关于angular自义定radio组合实现学习总结_第1张图片
桥豆麻袋。。。。这个插件还不对劲,根据要求是要再次点击radio就要清空查询条件的。
So不用能ng-zorro的组件了。大佬写了自定义的组件。(组件是大佬写的=。。=)

关于angular自义定radio组合实现学习总结_第2张图片
自定义插件如下:
关于angular自义定radio组合实现学习总结_第3张图片


  
  


  


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();
  }
}

关于angular自义定radio组合实现学习总结_第4张图片
通过 ElementRef 我们就可以封装不同平台下视图层中的 native 元素 (在浏览器环境中,native 元素通常是指 DOM 元素),最后借助于 Angular 提供的强大的依赖注入特性,我们就可以轻松地访问到 native 元素。
关于angular自义定radio组合实现学习总结_第5张图片

关于angular自义定radio组合实现学习总结_第6张图片
关于ControlValueAssessor的认识
在这里插入图片描述

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());
          });
      });
  }
}

不是自己写的看起来好难。
关于angular自义定radio组合实现学习总结_第7张图片
在这里插入图片描述

<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 不互斥,可多选,也可不选

   清除

关于angular自义定radio组合实现学习总结_第8张图片
关于angular自义定radio组合实现学习总结_第9张图片

你可能感兴趣的:(插件,知识储备学习)