diff --git a/components/auto-complete/demo/certain-category.ts b/components/auto-complete/demo/certain-category.ts
index abd8e71e5dc..bc8a622d11b 100644
--- a/components/auto-complete/demo/certain-category.ts
+++ b/components/auto-complete/demo/certain-category.ts
@@ -1,4 +1,4 @@
-import { ChangeDetectionStrategy, Component, OnInit, ViewEncapsulation } from '@angular/core';
+import { Component, OnInit, ViewEncapsulation } from '@angular/core';
export interface AutocompleteOptionGroups {
title: string;
@@ -9,7 +9,6 @@ export interface AutocompleteOptionGroups {
@Component({
selector: 'nz-demo-auto-complete-certain-category',
encapsulation: ViewEncapsulation.None,
- changeDetection: ChangeDetectionStrategy.OnPush,
template: `
`
})
@@ -25,7 +25,7 @@ export class NzDemoAutoCompleteNonCaseSensitiveComponent {
this.filteredOptions = this.options;
}
- onInput(value: string): void {
- this.filteredOptions = this.options.filter(option => option.toLowerCase().indexOf(value.toLowerCase()) === 0);
+ onChange(value: string): void {
+ this.filteredOptions = this.options.filter(option => option.toLowerCase().indexOf(value.toLowerCase()) !== -1);
}
}
diff --git a/components/auto-complete/demo/options.ts b/components/auto-complete/demo/options.ts
index f2e29ddfaa7..cf150bd91ac 100644
--- a/components/auto-complete/demo/options.ts
+++ b/components/auto-complete/demo/options.ts
@@ -9,7 +9,7 @@ import { Component, ViewEncapsulation } from '@angular/core';
placeholder="input here"
nz-input
[(ngModel)]="inputValue"
- (ngModelChange)="onChange($event)"
+ (input)="onInput($event)"
[nzAutocomplete]="auto"
/>
@@ -22,7 +22,8 @@ export class NzDemoAutoCompleteOptionsComponent {
inputValue: string;
options: string[] = [];
- onChange(value: string): void {
+ onInput(e: Event): void {
+ const value = (e.target as HTMLInputElement).value;
if (!value || value.indexOf('@') >= 0) {
this.options = [];
} else {
diff --git a/components/auto-complete/demo/uncertain-category.ts b/components/auto-complete/demo/uncertain-category.ts
index a4257c10b96..a711efda307 100644
--- a/components/auto-complete/demo/uncertain-category.ts
+++ b/components/auto-complete/demo/uncertain-category.ts
@@ -10,7 +10,7 @@ import { Component, ViewEncapsulation } from '@angular/core';
placeholder="input here"
nz-input
[(ngModel)]="inputValue"
- (ngModelChange)="onChange($event)"
+ (input)="onChange($event)"
[nzAutocomplete]="auto"
/>
@@ -20,22 +20,35 @@ import { Component, ViewEncapsulation } from '@angular/core';
-
- {{ option.value }} 在
-
+
+ Found {{ option.value }} on
+
{{ option.category }}
- 区块中
- 约 {{ option.count }} 个结果
+ {{ option.count }} results
`,
styles: [
`
+ .global-search-item {
+ display: flex;
+ }
+
+ .global-search-item-desc {
+ flex: auto;
+ text-overflow: ellipsis;
+ overflow: hidden;
+ }
+
.global-search-item-count {
- position: absolute;
- right: 16px;
+ flex: none;
}
`
]
@@ -44,8 +57,9 @@ export class NzDemoAutoCompleteUncertainCategoryComponent {
inputValue: string;
options: Array<{ value: string; category: string; count: number }> = [];
- onChange(value: string): void {
- this.options = new Array(this.getRandomInt(15, 5))
+ onChange(e: Event): void {
+ const value = (e.target as HTMLInputElement).value;
+ this.options = new Array(this.getRandomInt(5, 15))
.join('.')
.split('.')
.map((_item, idx) => ({
diff --git a/components/auto-complete/nz-autocomplete-option.component.ts b/components/auto-complete/nz-autocomplete-option.component.ts
index 4671c82192b..e4169452507 100644
--- a/components/auto-complete/nz-autocomplete-option.component.ts
+++ b/components/auto-complete/nz-autocomplete-option.component.ts
@@ -54,10 +54,12 @@ export class NzAutocompleteOptionComponent {
constructor(private changeDetectorRef: ChangeDetectorRef, private element: ElementRef) {}
- select(): void {
+ select(emit: boolean = true): void {
this.selected = true;
this.changeDetectorRef.markForCheck();
- this.emitSelectionChangeEvent();
+ if (emit) {
+ this.emitSelectionChangeEvent();
+ }
}
deselect(): void {
diff --git a/components/auto-complete/nz-autocomplete-trigger.directive.ts b/components/auto-complete/nz-autocomplete-trigger.directive.ts
index 30482a73d50..abf6cfa59a4 100644
--- a/components/auto-complete/nz-autocomplete-trigger.directive.ts
+++ b/components/auto-complete/nz-autocomplete-trigger.directive.ts
@@ -26,6 +26,7 @@ import {
ExistingProvider,
Inject,
Input,
+ NgZone,
OnDestroy,
Optional,
ViewContainerRef
@@ -33,7 +34,7 @@ import {
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
import { fromEvent, merge, Subscription } from 'rxjs';
-import { delay, distinct, map } from 'rxjs/operators';
+import { delay, distinct, map, take, tap } from 'rxjs/operators';
import { NzAutocompleteOptionComponent } from './nz-autocomplete-option.component';
import { NzAutocompleteComponent } from './nz-autocomplete.component';
@@ -92,8 +93,9 @@ export class NzAutocompleteTriggerDirective implements ControlValueAccessor, OnD
constructor(
private elementRef: ElementRef,
- private _overlay: Overlay,
+ private overlay: Overlay,
private viewContainerRef: ViewContainerRef,
+ private ngZone: NgZone,
// tslint:disable-next-line:no-any
@Optional() @Inject(DOCUMENT) private document: any
) {}
@@ -124,6 +126,7 @@ export class NzAutocompleteTriggerDirective implements ControlValueAccessor, OnD
openPanel(): void {
this.previousValue = this.elementRef.nativeElement.value;
this.attachOverlay();
+ this.updateStatus();
}
closePanel(): void {
@@ -210,8 +213,16 @@ export class NzAutocompleteTriggerDirective implements ControlValueAccessor, OnD
* Subscription data source changes event
*/
private subscribeOptionsChange(): Subscription {
- return this.nzAutocomplete.options.changes.pipe(delay(0)).subscribe(() => {
+ const firstStable = this.ngZone.onStable.asObservable().pipe(take(1));
+ const optionChanges = this.nzAutocomplete.options.changes.pipe(
+ tap(() => this.positionStrategy.reapplyLastPosition()),
+ delay(0)
+ );
+ return merge(firstStable, optionChanges).subscribe(() => {
this.resetActiveItem();
+ if (this.panelOpen) {
+ this.overlayRef!.updatePosition();
+ }
});
}
@@ -252,10 +263,11 @@ export class NzAutocompleteTriggerDirective implements ControlValueAccessor, OnD
return this.positionStrategy.positionChanges
.pipe(
map((position: ConnectedOverlayPositionChange) => position.connectionPair.originY),
- distinct()
+ distinct(),
+ delay(0)
)
.subscribe((position: VerticalConnectionPos) => {
- this.nzAutocomplete.dropDownPosition = position;
+ this.nzAutocomplete.updatePosition(position);
});
}
@@ -269,7 +281,7 @@ export class NzAutocompleteTriggerDirective implements ControlValueAccessor, OnD
}
if (!this.overlayRef) {
- this.overlayRef = this._overlay.create(this.getOverlayConfig());
+ this.overlayRef = this.overlay.create(this.getOverlayConfig());
}
if (this.overlayRef && !this.overlayRef.hasAttached()) {
@@ -279,15 +291,14 @@ export class NzAutocompleteTriggerDirective implements ControlValueAccessor, OnD
this.overlayBackdropClickSubscription = this.subscribeOverlayBackdropClick();
this.optionsChangeSubscription = this.subscribeOptionsChange();
}
-
this.nzAutocomplete.isOpen = this.panelOpen = true;
+ }
+
+ private updateStatus(): void {
+ if (this.overlayRef) {
+ this.overlayRef.updateSize({ width: this.nzAutocomplete.nzWidth || this.getHostWidth() });
+ }
this.nzAutocomplete.setVisibility();
- this.overlayRef.updateSize({ width: this.nzAutocomplete.nzWidth || this.getHostWidth() });
- setTimeout(() => {
- if (this.overlayRef) {
- this.overlayRef.updatePosition();
- }
- }, 150);
this.resetActiveItem();
if (this.activeOption) {
this.activeOption.scrollIntoViewIfNeeded();
@@ -303,7 +314,7 @@ export class NzAutocompleteTriggerDirective implements ControlValueAccessor, OnD
private getOverlayConfig(): OverlayConfig {
return new OverlayConfig({
positionStrategy: this.getOverlayPosition(),
- scrollStrategy: this._overlay.scrollStrategies.reposition(),
+ scrollStrategy: this.overlay.scrollStrategies.reposition(),
// default host element width
width: this.nzAutocomplete.nzWidth || this.getHostWidth()
});
@@ -322,19 +333,21 @@ export class NzAutocompleteTriggerDirective implements ControlValueAccessor, OnD
new ConnectionPositionPair({ originX: 'start', originY: 'bottom' }, { overlayX: 'start', overlayY: 'top' }),
new ConnectionPositionPair({ originX: 'start', originY: 'top' }, { overlayX: 'start', overlayY: 'bottom' })
];
- this.positionStrategy = this._overlay
+ this.positionStrategy = this.overlay
.position()
.flexibleConnectedTo(this.getConnectedElement())
- .withPositions(positions)
.withFlexibleDimensions(false)
- .withPush(false);
+ .withPush(false)
+ .withPositions(positions);
return this.positionStrategy;
}
private resetActiveItem(): void {
- const index = this.nzAutocomplete.getOptionIndex(this.nzAutocomplete.activeItem);
- if (this.nzAutocomplete.activeItem && index !== -1) {
+ const index = this.nzAutocomplete.getOptionIndex(this.previousValue);
+ this.nzAutocomplete.clearSelectedOptions(null, true);
+ if (index !== -1) {
this.nzAutocomplete.setActiveItem(index);
+ this.nzAutocomplete.activeItem.select(false);
} else {
this.nzAutocomplete.setActiveItem(this.nzAutocomplete.nzDefaultActiveFirstOption ? 0 : -1);
}
diff --git a/components/auto-complete/nz-autocomplete.component.html b/components/auto-complete/nz-autocomplete.component.html
index bf9efc03dbf..afabd335fec 100644
--- a/components/auto-complete/nz-autocomplete.component.html
+++ b/components/auto-complete/nz-autocomplete.component.html
@@ -4,7 +4,9 @@
[@.disabled]="noAnimation?.nzNoAnimation"
[nzNoAnimation]="noAnimation?.nzNoAnimation"
[@slideMotion]="dropDownPosition"
- [class.ant-select-dropdown-hidden]="!showPanel" [ngClass]="nzOverlayClassName" [ngStyle]="nzOverlayStyle">
+ [class.ant-select-dropdown-hidden]="!showPanel"
+ [ngClass]="nzOverlayClassName"
+ [ngStyle]="nzOverlayStyle">