Skip to content

Commit

Permalink
refactor(module:autocomplete): refactor autocomplete
Browse files Browse the repository at this point in the history
  • Loading branch information
hsuanxyz committed Nov 23, 2018
1 parent d432f5d commit 83bcc51
Show file tree
Hide file tree
Showing 6 changed files with 113 additions and 179 deletions.
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
<div class="ant-select-dropdown-menu-item-group-title">
<ng-container *ngIf="isLabelString; else labelTemplate">{{nzLabel}}</ng-container>
<ng-template #labelTemplate>
<ng-template [ngTemplateOutlet]="nzLabel"></ng-template>
</ng-template>
<ng-container *nzStringTemplateOutlet="nzLabel">{{nzLabel}}</ng-container>
</div>
<ul class="ant-select-dropdown-menu-item-group-list">
<ng-content select="nz-auto-option"></ng-content>
Expand Down
14 changes: 1 addition & 13 deletions components/auto-complete/nz-autocomplete-optgroup.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,20 +16,8 @@ import {
}
})
export class NzAutocompleteOptgroupComponent {
isLabelString: boolean;

/** group 的 label,支持 'string' 和 `TemplateRef` */
@Input()
set nzLabel(value: string | TemplateRef<void>) {
this.isLabelString = !(value instanceof TemplateRef);
this._label = value;
}

get nzLabel(): string | TemplateRef<void> {
return this._label;
}

_label: string | TemplateRef<void>;
@Input() nzLabel: string | TemplateRef<void>;

constructor() {
}
Expand Down
49 changes: 20 additions & 29 deletions components/auto-complete/nz-autocomplete-option.component.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
import {
ChangeDetectionStrategy,
ChangeDetectorRef,
Component, ElementRef, EventEmitter,
Input, Output
Component,
ElementRef,
EventEmitter,
Input,
Output
} from '@angular/core';

import { toBoolean } from '../core/util/convert';
import { InputBoolean } from '../core/util/convert';

export class NzOptionSelectionChange {
constructor(
Expand All @@ -32,57 +35,45 @@ export class NzOptionSelectionChange {
}
})
export class NzAutocompleteOptionComponent {
private disabled = false;

active = false;
selected = false;

/* tslint:disable-next-line:no-any */
@Input() nzValue: any;
@Input() nzLabel: string;

@Input()
get nzDisabled(): boolean {
return this.disabled;
}

set nzDisabled(value: boolean) {
this.disabled = toBoolean(value);
}

@Input() @InputBoolean() nzDisabled = false;
@Output() readonly selectionChange = new EventEmitter<NzOptionSelectionChange>();

active = false;
selected = false;

constructor(private changeDetectorRef: ChangeDetectorRef, private element: ElementRef) {
}

/** 选择 */
select(): void {
this.selected = true;
this.changeDetectorRef.markForCheck();
this.emitSelectionChangeEvent();
}

/** 取消选择 */
deselect(): void {
this.selected = false;
this.changeDetectorRef.markForCheck();
this.emitSelectionChangeEvent();
}

/** 获取用于显示的 label */
/** Git display label */
getLabel(): string {
return this.nzLabel || this.nzValue.toString();
}

/** 设置激活样式 (仅限样式) */
/** Set active (only styles) */
setActiveStyles(): void {
if (!this.active) {
this.active = true;
this.changeDetectorRef.markForCheck();
}
}

/** 设置非激活样式 (仅限样式) */
/** Unset active (only styles) */
setInactiveStyles(): void {
if (this.active) {
this.active = false;
Expand All @@ -92,18 +83,14 @@ export class NzAutocompleteOptionComponent {

scrollIntoViewIfNeeded(): void {
/* tslint:disable-next-line:no-string-literal */
if (this.element.nativeElement && this.element.nativeElement['scrollIntoViewIfNeeded']) {
if (this.element.nativeElement && this.element.nativeElement[ 'scrollIntoViewIfNeeded' ]) {
/* tslint:disable-next-line:no-string-literal */
setTimeout(() => this.element.nativeElement[ 'scrollIntoViewIfNeeded' ](false), 150);
setTimeout(() => this.element.nativeElement[ 'scrollIntoViewIfNeeded' ](false), 150);
}
}

private emitSelectionChangeEvent(isUserInput: boolean = false): void {
this.selectionChange.emit(new NzOptionSelectionChange(this, isUserInput));
}

selectViaInteraction(): void {
if (!this.disabled) {
if (!this.nzDisabled) {
this.selected = !this.selected;
if (this.selected) {
this.setActiveStyles();
Expand All @@ -115,4 +102,8 @@ export class NzAutocompleteOptionComponent {
}
}

private emitSelectionChangeEvent(isUserInput: boolean = false): void {
this.selectionChange.emit(new NzOptionSelectionChange(this, isUserInput));
}

}
115 changes: 54 additions & 61 deletions components/auto-complete/nz-autocomplete-trigger.directive.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,26 +56,20 @@ export function getNzAutocompleteMissingPanelError(): Error {
})
export class NzAutocompleteTriggerDirective implements ControlValueAccessor, OnDestroy {

/**
* 当前被激活的 Option
*/
/** Bind nzAutocomplete component */
@Input() nzAutocomplete: NzAutocompleteComponent;

_onChange: (value: {}) => void = () => {};
_onTouched = () => {};
panelOpen: boolean = false;

/** Current active option */
get activeOption(): NzAutocompleteOptionComponent {
if (this.nzAutocomplete && this.nzAutocomplete.options.length) {
return this.nzAutocomplete.activeItem;
}
}

panelOpen: boolean = false;

/** 用于绑定 nzAutocomplete 组件 */
@Input() nzAutocomplete: NzAutocompleteComponent;

constructor(private _element: ElementRef, private _overlay: Overlay,
private _viewContainerRef: ViewContainerRef,
// tslint:disable-next-line:no-any
@Optional() @Inject(DOCUMENT) private _document: any) {
}

private overlayRef: OverlayRef | null;
private portal: TemplatePortal<{}>;
private positionStrategy: FlexibleConnectedPositionStrategy;
Expand All @@ -85,8 +79,34 @@ export class NzAutocompleteTriggerDirective implements ControlValueAccessor, OnD
private overlayBackdropClickSubscription: Subscription;
private overlayPositionChangeSubscription: Subscription;

_onChange: (value: {}) => void = () => {};
_onTouched = () => {};
constructor(private elementRef: ElementRef, private _overlay: Overlay,
private viewContainerRef: ViewContainerRef,
// tslint:disable-next-line:no-any
@Optional() @Inject(DOCUMENT) private ngDocument: any) {
}

ngOnDestroy(): void {
this.destroyPanel();
}

// tslint:disable-next-line:no-any
writeValue(value: any): void {
this.setTriggerValue(value);
}

registerOnChange(fn: (value: {}) => {}): void {
this._onChange = fn;
}

registerOnTouched(fn: () => {}): void {
this._onTouched = fn;
}

setDisabledState(isDisabled: boolean): void {
const element: HTMLInputElement = this.elementRef.nativeElement;
element.disabled = isDisabled;
this.closePanel();
}

openPanel(): void {
this.attachOverlay();
Expand Down Expand Up @@ -115,8 +135,8 @@ export class NzAutocompleteTriggerDirective implements ControlValueAccessor, OnD
}

if (this.panelOpen && (keyCode === ESCAPE || keyCode === TAB)) {
// 通过 tab / ESC 关闭,重置输入标签 value
if (this.activeOption.getLabel() !== this.previousValue) {
// Reset value when tab / ESC close
if (this.activeOption && this.activeOption.getLabel() !== this.previousValue) {
this.setTriggerValue(this.previousValue);
}
this.closePanel();
Expand Down Expand Up @@ -155,7 +175,7 @@ export class NzAutocompleteTriggerDirective implements ControlValueAccessor, OnD

handleFocus(): void {
if (this.canOpen()) {
this.previousValue = this._element.nativeElement.value;
this.previousValue = this.elementRef.nativeElement.value;
this.openPanel();
}
}
Expand All @@ -164,31 +184,8 @@ export class NzAutocompleteTriggerDirective implements ControlValueAccessor, OnD
this._onTouched();
}

// tslint:disable-next-line:no-any
writeValue(value: any): void {
this.setTriggerValue(value);
}

registerOnChange(fn: (value: {}) => {}): void {
this._onChange = fn;
}

registerOnTouched(fn: () => {}): void {
this._onTouched = fn;
}

setDisabledState(isDisabled: boolean): void {
const element: HTMLInputElement = this._element.nativeElement;
element.disabled = isDisabled;
this.closePanel();
}

ngOnDestroy(): void {
this.destroyPanel();
}

/**
* 订阅数据源改变事件
* Subscription data source changes event
*/
private subscribeOptionsChange(): Subscription {
return this.nzAutocomplete.options.changes.pipe(
Expand All @@ -199,8 +196,7 @@ export class NzAutocompleteTriggerDirective implements ControlValueAccessor, OnD
}

/**
* 订阅 option 选择事件
* 并设置值
* Subscription option changes event and set the value
*/
private subscribeSelectionChange(): Subscription {
return this.nzAutocomplete.selectionChange
Expand All @@ -210,27 +206,25 @@ export class NzAutocompleteTriggerDirective implements ControlValueAccessor, OnD
}

/**
* 订阅组件外部的单击事件
* 并关闭弹窗
* Subscription external click and close panel
*/
private subscribeOverlayBackdropClick(): Subscription {
return merge<MouseEvent | TouchEvent>(
fromEvent<MouseEvent>(this._document, 'click'),
fromEvent<TouchEvent>(this._document, 'touchend')
fromEvent<MouseEvent>(this.ngDocument, 'click'),
fromEvent<TouchEvent>(this.ngDocument, 'touchend')
)
.subscribe((event: MouseEvent | TouchEvent) => {
const clickTarget = event.target as HTMLElement;

// 确保不是点击组件自身
if (clickTarget !== this._element.nativeElement && !this.overlayRef.overlayElement.contains(clickTarget) && this.panelOpen) {
// Make sure is not self
if (clickTarget !== this.elementRef.nativeElement && !this.overlayRef.overlayElement.contains(clickTarget) && this.panelOpen) {
this.closePanel();
}
});
}

/**
* 订阅 Overlay 位置改变事件
* 并重新设置动画方向
* Subscription overlay position changes and reset dropdown position
*/
private subscribeOverlayPositionChange(): Subscription {
return this.positionStrategy.positionChanges
Expand All @@ -249,7 +243,7 @@ export class NzAutocompleteTriggerDirective implements ControlValueAccessor, OnD
}

if (!this.overlayRef) {
this.portal = new TemplatePortal(this.nzAutocomplete.template, this._viewContainerRef);
this.portal = new TemplatePortal(this.nzAutocomplete.template, this.viewContainerRef);
this.overlayRef = this._overlay.create(this.getOverlayConfig());
}

Expand Down Expand Up @@ -287,13 +281,13 @@ export class NzAutocompleteTriggerDirective implements ControlValueAccessor, OnD
return new OverlayConfig({
positionStrategy: this.getOverlayPosition(),
scrollStrategy : this._overlay.scrollStrategies.reposition(),
// 如果没有设置 nzWidth 则使用 Host 元素的宽度
// default host element width
width : this.nzAutocomplete.nzWidth || this.getHostWidth()
});
}

private getConnectedElement(): ElementRef {
return this._element;
return this.elementRef;
}

private getHostWidth(): number {
Expand Down Expand Up @@ -325,23 +319,22 @@ export class NzAutocompleteTriggerDirective implements ControlValueAccessor, OnD
const value = option.nzValue;
this.setTriggerValue(option.getLabel());
this._onChange(value);
this._element.nativeElement.focus();
this.elementRef.nativeElement.focus();
this.closePanel();
}

private setTriggerValue(value: string | number | null): void {
this._element.nativeElement.value = value || '';
this.elementRef.nativeElement.value = value || '';
}

private doBackfill(): void {
if (this.nzAutocomplete.nzBackfill) {
// 只设置标签显示值
if (this.nzAutocomplete.nzBackfill && this.nzAutocomplete.activeItem) {
this.setTriggerValue(this.nzAutocomplete.activeItem.getLabel());
}
}

private canOpen(): boolean {
const element: HTMLInputElement = this._element.nativeElement;
const element: HTMLInputElement = this.elementRef.nativeElement;
return !element.readOnly && !element.disabled;
}
}
Loading

0 comments on commit 83bcc51

Please sign in to comment.