ng-ytl-zorro-antd
Version:
An enterprise-class UI components based on Ant Design and Angular
1,112 lines (974 loc) • 31.7 kB
text/typescript
/* tslint:disable:no-any */
import {
BACKSPACE,
DOWN_ARROW,
ENTER,
ESCAPE,
LEFT_ARROW,
RIGHT_ARROW,
UP_ARROW,
} from '@angular/cdk/keycodes';
import { ConnectedOverlayPositionChange, ConnectionPositionPair } from '@angular/cdk/overlay';
import {
forwardRef,
AfterViewInit,
ChangeDetectorRef,
Component,
ElementRef,
EventEmitter,
HostBinding,
HostListener,
Input,
OnChanges,
OnDestroy,
OnInit,
Output,
Renderer2,
SimpleChanges,
TemplateRef,
ViewChild,
ViewEncapsulation,
} from '@angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
const ESC = 27;
import { dropDownAnimation } from '../core/animation/dropdown-animations';
import { toBoolean } from '../util/convert';
// TODO: remove this as used nowhere
const noop = () => null;
function toArray<T>(value: T | T[]): T[] {
let ret: T[];
if (value == null) {
ret = [];
} else if (!Array.isArray(value)) {
ret = [value];
} else {
ret = value;
}
return ret;
}
function arrayEquals<T>(array1: T[], array2: T[]): boolean {
if (!array1 || !array2 || array1.length !== array2.length) {
return false;
}
const len = array1.length;
for (let i = 0; i < len; i++) {
if (array1[i] !== array2[i]) {
return false;
}
}
return true;
}
const defaultDisplayRender = label => label.join(' / ');
export type CascaderExpandTrigger = 'click' | 'hover';
export type CascaderTriggerType = 'click' | 'hover';
export interface CascaderOption {
value?: string;
label?: string;
title?: string;
disabled?: boolean;
loading?: boolean;
isLeaf?: boolean;
parent?: CascaderOption;
children?: CascaderOption[];
[key: string]: any;
}
export interface DisplayLabelContext {
labels?: string[];
selectedOptions?: CascaderOption[];
}
export class NzCascaderComponent implements OnInit, OnDestroy, OnChanges, AfterViewInit, ControlValueAccessor {
private _allowClear = true;
private _disabled = false;
private _enableCache = true;
private _showArrow = true;
private _showInput = true;
private _showSearch = false;
private _changeOnSelect = false;
_el: HTMLElement;
_prefixCls = 'ant-cascader';
_inputPrefixCls = 'ant-input';
_dropDownPosition = 'bottom';
_focused = false;
_popupVisible = false;
_displayLabel: string | TemplateRef<void>;
_displayLabelIsTemplate = false;
_displayLabelContext: DisplayLabelContext = {};
/* tslint:disable-next-line:variable-name */
__inputValue = '';
get _inputValue(): string {
return this.__inputValue;
}
set _inputValue(inputValue: string) {
this.__inputValue = inputValue;
if (inputValue.length) {
this._addHostClass(`${this._prefixCls}-picker-with-value`);
} else {
this._removeHostClass(`${this._prefixCls}-picker-with-value`);
}
}
// check if change happened
_lastValue: any[];
// selection will trigger value change
_selectedOptions: CascaderOption[] = [];
// activaction will not triiger value change
_activatedOptions: CascaderOption[] = [];
// all data columns
_nzColumns: CascaderOption[][] = [];
// 点击Document的事件(一般用于点击后隐藏菜单)
private _clickOutsideHandler: () => void;
private _touchOutsideHandler: () => void;
private _delayTimer: any;
// ngModel Access
onChange: any = Function.prototype;
onTouched: any = Function.prototype;
/** Whether is disabled */
set nzDisabled(value: boolean) {
this._disabled = toBoolean(value);
}
get nzDisabled(): boolean {
return this._disabled;
}
/** Input size, one of `large` `default` `small` */
nzSize: 'large' | 'default' | 'small' = 'default';
/** Input placeholder */
nzPlaceHolder = 'Please select';
/** Whether show input box. Defaults to `true`. */
set nzShowInput(value: boolean) {
this._showInput = toBoolean(value);
}
get nzShowInput(): boolean {
return this._showInput;
}
/** Whether can search. Defaults to `false`. */
set nzShowSearch(value: boolean) {
this._showSearch = toBoolean(value);
}
get nzShowSearch(): boolean {
return this._showSearch;
}
/** Whether allow clear. Defaults to `true`. */
set nzAllowClear(value: boolean) {
this._allowClear = toBoolean(value);
}
get nzAllowClear(): boolean {
return this._allowClear;
}
/** Hover text for the clear icon */
nzClearText = 'Clear';
/** Whether to show arrow */
set nzShowArrow(value: boolean) {
this._showArrow = toBoolean(value);
}
get nzShowArrow(): boolean {
return this._showArrow;
}
/** Specify content to show when no result matches. */
nzNotFoundContent = 'Not Found';
/** Additional className of popup overlay */
nzPopupClassName: string;
/** Additional className of popup overlay column */
nzColumnClassName: string;
/** Options for first column, sub column will be load async */
nzOptions: CascaderOption[];
/** Whether cache children when they were loaded asych */
set nzEnableCache(value: boolean) {
this._enableCache = toBoolean(value);
}
get nzEnableCache(): boolean {
return this._enableCache;
}
/** Expand column item when click or hover, one of 'click' 'hover' */
nzExpandTrigger: CascaderExpandTrigger = 'click';
/** Change value on each selection if set to true */
set nzChangeOnSelect(value: boolean) {
this._changeOnSelect = toBoolean(value);
}
get nzChangeOnSelect(): boolean {
return this._changeOnSelect;
}
/** Change value on selection only if this function returns `true` */
nzChangeOn: (option: CascaderOption, level: number) => boolean;
/** Delay time to show when mouse enter, when `nzExpandTrigger` is `hover`. */
nzMouseEnterDelay = 150; // ms
/** Delay time to hide when mouse enter, when `nzExpandTrigger` is `hover`. */
nzMouseLeaveDelay = 150; // ms
/** Triggering mode: can be Array<'click'|'hover'> */
nzTriggerAction: CascaderTriggerType | CascaderTriggerType[] = ['click'];
/** Render function of displaying selected options */
nzDisplayRender: (label: string[], selectedOptions: CascaderOption[]) => string | TemplateRef<any>;
/** Property name for getting `value` in the option */
nzValueProperty = 'value';
/** Property name for getting `label` in the option */
nzLabelProperty = 'label';
menu: ElementRef;
tabIndex = '0';
/** Event: emit on popup show or hide */
nzVisibleChange = new EventEmitter<boolean>();
/** Event: emit on values changed */
nzChange = new EventEmitter<any[]>();
/** Event: emit on values and selection changed */
nzSelectionChange = new EventEmitter<CascaderOption[]>();
/**
* Event: emit on option selected, event data:{option: any, index: number}
*/
nzSelect = new EventEmitter<{
option: CascaderOption,
index: number
}>();
/**
* Event: emit before loading children. event data:{option: any|null, index: number, resolve, reject}
*/
nzLoad = new EventEmitter<{
option: CascaderOption,
index: number,
resolve(children: CascaderOption[]): void,
reject(): void
}>();
/** Event: emit on the clear button clicked */
nzClear = new EventEmitter<any>();
onPositionChange(position: ConnectedOverlayPositionChange): void {
const _position = position.connectionPair.originY === 'bottom' ? 'bottom' : 'top';
if (this._dropDownPosition !== _position) {
this._dropDownPosition = _position;
this._cdr.detectChanges();
}
}
nzFocus(): void {
this._focused = true;
this._addHostClass(`${this._prefixCls}-focused`);
}
nzBlur(): void {
this._focused = false;
this._removeHostClass(`${this._prefixCls}-focused`);
}
get _pickerLabelCls(): any {
return {
[`${this._prefixCls}-picker-label`]: true
};
}
get _arrowCls(): any {
return {
[`${this._prefixCls}-picker-arrow`] : true,
[`${this._prefixCls}-picker-arrow-expand`]: this._popupVisible
};
}
get _clearCls(): any {
return {
[`${this._prefixCls}-picker-clear`]: true
};
}
get _inputCls(): any {
return {
[`${this._prefixCls}-input`] : 1,
[`${this._inputPrefixCls}-disabled`]: this.nzDisabled,
[`${this._inputPrefixCls}-lg`] : this.nzSize === 'large',
[`${this._inputPrefixCls}-sm`] : this.nzSize === 'small',
};
}
get _menuCls(): any {
return {
[`${this._prefixCls}-menus`] : true,
[`${this._prefixCls}-menus-hidden`]: !this._popupVisible,
[`${this.nzPopupClassName}`] : this.nzPopupClassName
};
}
/** 获取菜单中列的样式 */
get _columnCls(): any {
return {
[`${this._prefixCls}-menu`] : true,
[`${this.nzColumnClassName}`]: this.nzColumnClassName
};
}
/** 获取列中Option的样式 */
_getOptionCls(option: CascaderOption, index: number): any {
return {
[`${this._prefixCls}-menu-item`] : true,
[`${this._prefixCls}-menu-item-expand`] : !option.isLeaf,
[`${this._prefixCls}-menu-item-active`] : this._isActiveOption(option, index),
[`${this._prefixCls}-menu-item-disabled`]: option.disabled,
[`${this._prefixCls}-menu-item-loading`] : option.loading
};
}
_getLabel(): string | TemplateRef<void> {
return this._displayLabelIsTemplate ? '' : this._displayLabel;
}
/** prevent input change event */
_handlerInputChange(event: Event): void {
event.stopPropagation();
}
/** input blur */
_handleInputBlur(event: Event): void {
if (!this.nzShowSearch) {
return;
}
if (this._popupVisible) {
this.nzFocus();
} else {
this.nzBlur();
}
}
/** input focus */
_handleInputFocus(event: Event): void {
if (!this.nzShowSearch) {
return;
}
this.nzFocus();
}
/** input key down */
_handleInputKeyDown(event: KeyboardEvent): void { }
_setInputValue(inputValue: any, fireSearch: boolean = true): void {
if (inputValue !== this._inputValue) {
this._inputValue = inputValue;
}
}
_hasInput(): boolean {
return this._inputValue.length > 0;
}
_hasSelection(): boolean {
return this._selectedOptions.length > 0;
}
/** Whether the clear button is visible */
get _showClearIcon(): boolean {
const isSelected = this._hasSelection();
const isHasInput = this._hasInput();
return this.nzAllowClear && !this.nzDisabled && (isSelected || isHasInput);
}
/** clear the input box and selected options */
_clearSelection(event: Event): void {
if (event) {
event.preventDefault();
event.stopPropagation();
}
this._displayLabel = '';
this._displayLabelIsTemplate = false;
this._selectedOptions = [];
this._activatedOptions = [];
this._setInputValue('', false);
this.setPopupVisible(false);
// trigger change event
this._onValueChange();
}
get _displayRender(): (label: string[], selectedOptions: CascaderOption[]) => string | TemplateRef<any> {
return this.nzDisplayRender || defaultDisplayRender;
}
_buildDisplayLabel(): void {
const selectedOptions = this._selectedOptions;
const labels: string[] = selectedOptions.map(o => o[this.nzLabelProperty || 'label']);
// 设置当前控件的显示值
this._displayLabel = this._displayRender.call(this, labels, selectedOptions);
this._displayLabelIsTemplate = !(typeof this._displayLabel === 'string');
this._displayLabelContext = {labels, selectedOptions};
}
/** 由用户来定义点击后是否变更 */
_isChangeOn(option: CascaderOption, index: number): boolean {
if (typeof this.nzChangeOn === 'function') {
return this.nzChangeOn(option, index) === true;
}
return false;
}
onKeyDown(event: KeyboardEvent): void {
const keyCode = event.keyCode;
if (keyCode !== DOWN_ARROW &&
keyCode !== UP_ARROW &&
keyCode !== LEFT_ARROW &&
keyCode !== RIGHT_ARROW &&
keyCode !== ENTER &&
keyCode !== BACKSPACE &&
keyCode !== ESC) {
return;
}
// Press any keys above to reopen menu
if (!this._isPopupVisible() &&
keyCode !== BACKSPACE &&
keyCode !== ESC) {
this.setPopupVisible(true);
return;
}
// Press ESC to close menu
if (keyCode === ESC) {
this.setPopupVisible(false);
return;
}
if (this._isPopupVisible()) {
event.preventDefault();
if (keyCode === DOWN_ARROW) {
this._moveDown();
}
if (keyCode === UP_ARROW) {
this._moveUp();
}
if (keyCode === LEFT_ARROW) {
this._moveLeft();
}
if (keyCode === RIGHT_ARROW) {
this._moveRight();
}
}
}
_onTriggerClick(event: MouseEvent): void {
if (this.nzDisabled) {
return;
}
this.onTouched(); // set your control to 'touched'
if (this._isClickTiggerAction()) {
this._delaySetPopupVisible(!this._popupVisible, 100);
}
}
_onTriggerMouseEnter(event: MouseEvent): void {
if (this.nzDisabled) {
return;
}
if (this._isPointerTiggerAction()) {
this._delaySetPopupVisible(true, this.nzMouseEnterDelay);
}
}
_onTriggerMouseLeave(event: MouseEvent): void {
if (this.nzDisabled) {
return;
}
if (!this._isPopupVisible()) {
return;
}
if (this._isPointerTiggerAction()) {
const currEl = this._el;
const popupEl = this.menu && this.menu.nativeElement as HTMLElement;
if (currEl.contains(event.target as Node) ||
(popupEl && popupEl.contains(event.target as Node))) {
return; // 还在菜单内部
}
this._delaySetPopupVisible(false, this.nzMouseLeaveDelay);
}
}
_isClickTiggerAction(): boolean {
if (typeof this.nzTriggerAction === 'string') {
return this.nzTriggerAction === 'click';
}
return this.nzTriggerAction.indexOf('click') !== -1;
}
_isPointerTiggerAction(): boolean {
if (typeof this.nzTriggerAction === 'string') {
return this.nzTriggerAction === 'hover';
}
return this.nzTriggerAction.indexOf('hover') !== -1;
}
_closeMenu(): void {
this._clearDelayTimer();
this.setPopupVisible(false);
}
/**
* 显示或者隐藏菜单
*
* @param visible true-显示,false-隐藏
* @param delay 延迟时间
*/
_delaySetPopupVisible(visible: boolean, delay: number): void {
this._clearDelayTimer();
if (delay) {
this._delayTimer = setTimeout(() => {
this.setPopupVisible(visible);
this._clearDelayTimer();
}, delay);
} else {
this.setPopupVisible(visible);
}
}
_isPopupVisible(): boolean {
return this._popupVisible;
}
setPopupVisible(popupVisible: boolean): void {
if (this.nzDisabled) {
return;
}
if (this._popupVisible !== popupVisible) {
this._popupVisible = popupVisible;
// We must listen to `mousedown` or `touchstart`, edge case:
// https://github.com/ant-design/ant-design/issues/5804
// https://github.com/react-component/calendar/issues/250
// https://github.com/react-component/trigger/issues/50
if (popupVisible) {
if (!this._clickOutsideHandler) {
this._clickOutsideHandler = this._render.listen('document', 'mousedown', this._onDocumentClick.bind(this));
}
// always hide on mobile
if (!this._touchOutsideHandler) {
this._touchOutsideHandler = this._render.listen('document', 'touchstart', this._onDocumentClick.bind(this));
}
}
if (!popupVisible) {
this._clearOutsideHandler();
}
if (popupVisible) {
this._beforeVisible();
}
this.nzVisibleChange.emit(popupVisible);
}
}
/** load init data if necessary */
_beforeVisible(): void {
if (!this._nzColumns.length) {
new Promise((resolve, reject) => {
this.nzLoad.emit({
option: null,
index: -1,
resolve,
reject
});
}).then((children: CascaderOption[]) => {
this._setColumnData(children, 0);
}, (reason: any) => {
// should not be here
});
}
}
_onDocumentClick(event: MouseEvent): void {
const target = event.target as Node;
const popupEl = this.menu && this.menu.nativeElement as HTMLElement;
if (!this._el.contains(target) && !popupEl.contains(target)) {
this.setPopupVisible(false);
}
}
_clearOutsideHandler(): void {
if (this._clickOutsideHandler) {
this._clickOutsideHandler(); // Removes "listen" listener
this._clickOutsideHandler = null;
}
if (this._touchOutsideHandler) {
this._touchOutsideHandler(); // Removes "listen" listener
this._touchOutsideHandler = null;
}
}
_clearDelayTimer(): void {
if (this._delayTimer) {
clearTimeout(this._delayTimer);
this._delayTimer = null;
}
}
/** 获取Option的值,例如,可以指定labelProperty="name"来取Name */
_getOptionLabel(option: CascaderOption): any {
return option[this.nzLabelProperty || 'label'];
}
/** 获取Option的值,例如,可以指定valueProperty="id"来取ID */
_getOptionValue(option: CascaderOption): any {
return option[this.nzValueProperty || 'value'];
}
_isActiveOption(option: CascaderOption, index: number): boolean {
const activeOpt = this._activatedOptions[index];
if (activeOpt === option) {
return true;
}
if (activeOpt && this._getOptionValue(activeOpt) === this._getOptionValue(option)) {
return true;
}
return false;
}
/**
* 设置某列的激活的菜单选项
*
* @param option 菜单选项
* @param index 选项所在的列组的索引
*/
_setActiveOption(option: CascaderOption, index: number): void {
if (!option || option.disabled) {
return;
}
this._activatedOptions[index] = option;
// 当直接选择最后一级时,前面的选项要补全。例如,选择“城市”,则自动补全“国家”、“省份”
for (let i = index - 1; i >= 0; i--) {
if (!this._activatedOptions[i]) {
this._activatedOptions[i] = this._activatedOptions[i + 1].parent;
}
}
// 截断多余的选项,如选择“省份”,则只会有“国家”、“省份”,去掉“城市”、“区县”
if (index < this._activatedOptions.length - 1) {
this._activatedOptions = this._activatedOptions.slice(0, index + 1);
}
// trigger select event, and display label
this._onSelectOption(option, index);
}
_onSelectOption(option: CascaderOption, index: number): void {
// trigger `nzSelect` event
this.nzSelect.emit({
option,
index
});
// load children directly
if (option.children && option.children.length) {
option.isLeaf = false;
option.children.forEach(child => child.parent = option);
this._setColumnData(option.children, index + 1);
} else if (!option.isLeaf) {
// load children async
new Promise((resolve, reject) => {
this.nzLoad.emit({
option,
index,
resolve,
reject
});
}).then((children: CascaderOption[]) => {
children.forEach(child => child.parent = option);
this._setColumnData(children, index + 1);
if (this.nzEnableCache) {
option.children = children; // next time we load children directly
}
}, (reason: any) => {
option.isLeaf = true;
});
} else {
// clicking leaf node will remove any children columns
if (index < this._nzColumns.length - 1) {
this._nzColumns = this._nzColumns.slice(0, index + 1);
}
}
// 生成显示
if (option.isLeaf || this.nzChangeOnSelect || this._isChangeOn(option, index)) {
this._selectedOptions = this._activatedOptions;
// 设置当前控件的显示值
this._buildDisplayLabel();
// 触发变更事件
this._onValueChange();
}
// close menu if click on leaf
if (option.isLeaf) {
this._delaySetPopupVisible(false, this.nzMouseLeaveDelay);
}
}
_setColumnData(options: CascaderOption[], index: number): void {
if (!arrayEquals(this._nzColumns[index], options)) {
this._nzColumns[index] = options;
if (index < this._nzColumns.length - 1) {
this._nzColumns = this._nzColumns.slice(0, index + 1);
}
}
}
/**
* 鼠标点击选项
*
* @param option 菜单选项
* @param index 选项所在的列组的索引
* @param event 鼠标事件
*/
_onOptionClick(option: CascaderOption, index: number, event: Event): void {
event.preventDefault();
// Keep focused state for keyboard support
this._el.focus();
if (option && option.disabled) {
return;
}
this._setActiveOption(option, index);
}
/**
* press `up` or `down` arrow to select the sibling option.
*/
_moveUpOrDown(isUp: boolean): void {
const columnIndex = Math.max(this._activatedOptions.length - 1, 0);
// 该组中已经被激活的选项
const activeOption = this._activatedOptions[columnIndex];
// 该组所有的选项,用于遍历获取下一个被激活的选项
const options = this._nzColumns[columnIndex];
if (!options || !options.length) {
return;
}
const length = options.length;
let nextOptIndex = -1;
if (!activeOption) { // 该列还没有选中的选项
nextOptIndex = isUp ? length : -1;
} else {
nextOptIndex = options.indexOf(activeOption);
}
while (true) {
nextOptIndex = isUp ? nextOptIndex - 1 : nextOptIndex + 1;
if (nextOptIndex < 0 || nextOptIndex >= length) {
break;
}
const nextOption = options[nextOptIndex];
if (!nextOption || nextOption.disabled) {
continue;
}
this._setActiveOption(nextOption, columnIndex);
break;
}
}
_moveUp(): void {
this._moveUpOrDown(true);
}
_moveDown(): void {
this._moveUpOrDown(false);
}
/**
* press `left` arrow to remove the last selected option.
* If there is no option selected, emit `nzClear` event.
*/
_moveLeft(): void {
const options = this._selectedOptions;
if (options.length) {
options.pop(); // Remove the last one
const len = options.length;
if (len) {
this._setActiveOption(options[len - 1], len - 1);
} else {
this.nzClear.emit();
}
}
}
/**
* press `right` arrow to select the next column option.
*/
_moveRight(): void {
const columns = this._nzColumns;
const length = this._selectedOptions.length;
if (length === 0) {
return;
}
const nextColIndex = length;
const options = columns.length > nextColIndex ? columns[nextColIndex] : null;
if (options) { // 存在`下级选项`
const len = options.length;
for (let i = 0; i < len; i++) {
const activeOpt = options[i];
if (activeOpt && !activeOpt.disabled) {
this._setActiveOption(activeOpt, nextColIndex);
return;
}
}
}
}
/**
* 鼠标划入选项
*
* @param option 菜单选项
* @param index 选项所在的列组的索引
* @param event 鼠标事件
*/
_onOptionMouseEnter(option: CascaderOption, index: number, event: Event): void {
event.preventDefault();
if (this.nzExpandTrigger === 'hover' && !option.isLeaf) {
this._delaySelect(option, index, true);
}
}
/**
* 鼠标划出选项
*
* @param option 菜单选项
* @param index 选项所在的列组的索引
* @param event 鼠标事件
*/
_onOptionMouseLeave(option: CascaderOption, index: number, event: Event): void {
event.preventDefault();
if (this.nzExpandTrigger === 'hover' && !option.isLeaf) {
this._delaySelect(option, index, false);
}
}
_delaySelect(option: CascaderOption, index: number, doSelect: boolean): void {
if (this._delayTimer) {
clearTimeout(this._delayTimer);
this._delayTimer = null;
}
if (doSelect) {
this._delayTimer = setTimeout(() => {
this._setActiveOption(option, index);
this._delayTimer = null;
}, 150);
}
}
_getSubmitValue(): any[] {
const values: any[] = [];
this._selectedOptions.forEach(option => {
values.push(this._getOptionValue(option));
});
return values;
}
_onValueChange(): void {
const value = this._getSubmitValue();
if (!arrayEquals(this._lastValue, value)) {
this._lastValue = value;
this.onChange(value); // Angular need this
if (value.length === 0) {
this.nzClear.emit(); // first trigger `clear` and then `change`
}
this.nzSelectionChange.emit(this._selectedOptions);
this.nzChange.emit(value);
}
}
constructor(
private _elementRef: ElementRef,
private _render: Renderer2,
private _cdr: ChangeDetectorRef
) {
this._el = this._elementRef.nativeElement;
}
_addHostClass(classname: string): void {
this._render.addClass(this._el, classname);
}
_removeHostClass(classname: string): void {
this._render.removeClass(this._el, classname);
}
/**
* Write a new value to the element.
*
* @Override (From ControlValueAccessor interface)
*/
writeValue(value: any): void {
const array: any[] = [];
toArray(value).forEach((v: any, index: number) => {
if (typeof v !== 'object') {
const obj = {};
obj[this.nzValueProperty] = v;
obj[this.nzLabelProperty] = v;
array[index] = obj;
} else {
array[index] = v;
}
});
this._activatedOptions = array;
this._selectedOptions = array;
this._buildDisplayLabel();
}
registerOnChange(fn: (_: any) => {}): void {
this.onChange = fn;
}
registerOnTouched(fn: () => {}): void {
this.onTouched = fn;
}
setDisabledState(isDisabled: boolean): void {
if (isDisabled) {
this._closeMenu();
this._addHostClass(`${this._prefixCls}-picker-disabled`);
} else {
this._removeHostClass(`${this._prefixCls}-picker-disabled`);
}
this.nzDisabled = isDisabled;
}
ngOnInit(): void {
// 设置第一列
if (this.nzOptions && this.nzOptions.length) {
this._nzColumns.push(this.nzOptions);
}
}
ngOnDestroy(): void {
if (this._delayTimer) {
clearTimeout(this._delayTimer);
this._delayTimer = null;
}
}
ngOnChanges(changes: SimpleChanges): void {
const nzDisabled = changes.nzDisabled;
if (nzDisabled) {
if (nzDisabled.currentValue) {
this._addHostClass(`${this._prefixCls}-picker-disabled`);
} else {
this._removeHostClass(`${this._prefixCls}-picker-disabled`);
}
}
const nzOptions = changes.nzOptions;
if (nzOptions && !nzOptions.isFirstChange()) {
this._nzColumns.splice(0);
const newOptions: CascaderOption[] = nzOptions.currentValue;
if (newOptions && newOptions.length) {
this._nzColumns.push(newOptions);
this._clearSelection(null);
}
}
}
ngAfterViewInit(): void {
this._addHostClass(this._prefixCls);
this._addHostClass(`${this._prefixCls}-picker`);
}
}