Skip to content

Commit

Permalink
feat(typeahead): removed old injector usage (#1321)
Browse files Browse the repository at this point in the history
refs #1318
  • Loading branch information
valorkin authored Dec 12, 2016
1 parent 3e53b7d commit a86c340
Show file tree
Hide file tree
Showing 6 changed files with 78 additions and 61 deletions.
2 changes: 1 addition & 1 deletion src/component-loader/component-loader.class.ts
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ export class ComponentLoader<T> {
}

private _subscribePositioning(): void {
if (this._zoneSubscription) {
if (this._zoneSubscription || !this.attachment) {
return;
}

Expand Down
3 changes: 1 addition & 2 deletions src/datepicker/datepicker.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import { DatePickerComponent } from './datepicker.component';
import { DayPickerComponent } from './daypicker.component';
import { MonthPickerComponent } from './monthpicker.component';
import { YearPickerComponent } from './yearpicker.component';
import { ComponentsHelper } from '../utils/components-helper.service';
import { DatepickerConfig } from './datepicker.config';

@NgModule({
Expand All @@ -16,7 +15,7 @@ import { DatepickerConfig } from './datepicker.config';
MonthPickerComponent, YearPickerComponent],
exports: [DatePickerComponent, DatePickerInnerComponent, DayPickerComponent, FormsModule,
MonthPickerComponent, YearPickerComponent],
providers: [ComponentsHelper, DatepickerConfig]
providers: [DatepickerConfig]
})
export class DatepickerModule {
}
4 changes: 2 additions & 2 deletions src/spec/typeahead.directive.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ describe('Directive: Typeahead', () => {
});

it('should not set the container reference', () => {
expect(directive.container).toBeFalsy();
expect(directive._container).toBeFalsy();
});
});

Expand All @@ -107,7 +107,7 @@ describe('Directive: Typeahead', () => {
});

it('should set the container reference', () => {
expect(directive.container).toBeTruthy();
expect(directive._container).toBeTruthy();
});

it('should result in a total of 2 matches, when \"Ala\" is entered', fakeAsync(() => {
Expand Down
20 changes: 3 additions & 17 deletions src/typeahead/typeahead-container.component.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,12 @@
import { Component, ElementRef, TemplateRef, ViewEncapsulation } from '@angular/core';

import { Ng2BootstrapConfig, Ng2BootstrapTheme } from '../utils/ng2-bootstrap-config';
import { positionService } from '../utils/position';
import { TypeaheadOptions } from './typeahead-options.class';
import { TypeaheadUtils } from './typeahead-utils';
import { TypeaheadDirective } from './typeahead.directive';
import { TypeaheadMatch } from './typeahead-match.class';

const bs4 = `
<div class="dropdown-menu"
[ngStyle]="{top: top, left: left, display: 'block'}"
(mouseleave)="focusLost()">
<template ngFor let-match let-i="index" [ngForOf]="matches">
<h6 *ngIf="match.isHeader()" class="dropdown-header">{{match}}</h6>
Expand Down Expand Up @@ -38,7 +35,6 @@ const bs4 = `

const bs3 = `
<ul class="dropdown-menu"
[ngStyle]="{top: top, left: left, display: 'block'}"
(mouseleave)="focusLost()">
<template ngFor let-match let-i="index" [ngForOf]="matches">
<li *ngIf="match.isHeader()" class="dropdown-header">{{match}}</li>
Expand Down Expand Up @@ -67,6 +63,8 @@ let isBS4 = Ng2BootstrapConfig.theme === Ng2BootstrapTheme.BS4;
@Component({
selector: 'typeahead-container',
template: isBS4 ? bs4 : bs3,
// tslint:disable-next-line
host: {'[class]': '"dropdown open"' },
encapsulation: ViewEncapsulation.None
})
export class TypeaheadContainerComponent {
Expand All @@ -82,9 +80,8 @@ export class TypeaheadContainerComponent {
protected _matches:TypeaheadMatch[] = [];
protected placement:string;

public constructor(element:ElementRef, options:TypeaheadOptions) {
public constructor(element:ElementRef) {
this.element = element;
Object.assign(this, options);
}

public get matches():TypeaheadMatch[] {
Expand All @@ -105,17 +102,6 @@ export class TypeaheadContainerComponent {
return this.parent ? this.parent.typeaheadItemTemplate : undefined;
}

public position(hostEl:ElementRef):void {
this.top = '0px';
this.left = '0px';
let p = positionService
.positionElements(hostEl.nativeElement,
this.element.nativeElement.children[0],
this.placement, false);
this.top = p.top + 'px';
this.left = p.left + 'px';
}

public selectActiveMatch():void {
this.selectMatch(this._active);
}
Expand Down
107 changes: 69 additions & 38 deletions src/typeahead/typeahead.directive.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import {
ComponentRef, Directive, ElementRef, EventEmitter, HostListener, Input, OnInit, Output,
ReflectiveInjector, Renderer, TemplateRef, ViewContainerRef
ComponentRef, Directive, ElementRef, EventEmitter, HostListener, Input,
OnInit, Output,
ReflectiveInjector, Renderer, TemplateRef, ViewContainerRef, OnDestroy
} from '@angular/core';
import { FormControl, NgControl } from '@angular/forms';

Expand All @@ -19,6 +20,7 @@ import 'rxjs/add/operator/toArray';

import { ComponentsHelper } from '../utils/components-helper.service';
import { TypeaheadMatch } from './typeahead-match.class';
import { ComponentLoaderFactory, ComponentLoader } from '../component-loader';

/* tslint:disable-next-line */
const KeyboardEvent = (global as any).KeyboardEvent as KeyboardEvent;
Expand All @@ -28,7 +30,7 @@ const KeyboardEvent = (global as any).KeyboardEvent as KeyboardEvent;
selector: '[typeahead][ngModel],[typeahead][formControlName]'
/* tslint:enable */
})
export class TypeaheadDirective implements OnInit {
export class TypeaheadDirective implements OnInit, OnDestroy {
@Output() public typeaheadLoading:EventEmitter<boolean> = new EventEmitter<boolean>(false);
@Output() public typeaheadNoResults:EventEmitter<boolean> = new EventEmitter<boolean>(false);
@Output() public typeaheadOnSelect:EventEmitter<TypeaheadMatch> = new EventEmitter<TypeaheadMatch>(false);
Expand All @@ -46,32 +48,39 @@ export class TypeaheadDirective implements OnInit {
@Input() public typeaheadPhraseDelimiters:string = '\'"';
@Input() public typeaheadItemTemplate:TemplateRef<any>;

/**
* A selector specifying the element the typeahead should be appended to.
* Currently only supports "body".
*/
@Input() public container: string;

// not yet implemented
// @Input() protected typeaheadAppendToBody:boolean;
// @Input() protected typeaheadEditable:boolean;
// @Input() protected typeaheadFocusFirst:boolean;
// @Input() protected typeaheadInputFormatter:any;
// @Input() protected typeaheadSelectOnExact:boolean;
// @Input() protected typeaheadSelectOnBlur:boolean;
// @Input() protected typeaheadFocusOnSelect:boolean;

public container:TypeaheadContainerComponent;
public _container:TypeaheadContainerComponent;
public isTypeaheadOptionsListActive:boolean = false;

protected keyUpEventEmitter:EventEmitter<any> = new EventEmitter();
protected _matches:TypeaheadMatch[];
protected placement:string = 'bottom-left';
protected popup:ComponentRef<TypeaheadContainerComponent>;
// protected popup:ComponentRef<TypeaheadContainerComponent>;

protected ngControl:NgControl;
protected viewContainerRef:ViewContainerRef;
protected element:ElementRef;
protected renderer:Renderer;
protected componentsHelper:ComponentsHelper;

private _typeahead: ComponentLoader<TypeaheadContainerComponent>;

@HostListener('keyup', ['$event'])
public onChange(e:any):void {
if (this.container) {
if (this._container) {
// esc
if (e.keyCode === 27) {
this.hide();
Expand All @@ -80,19 +89,19 @@ export class TypeaheadDirective implements OnInit {

// up
if (e.keyCode === 38) {
this.container.prevActiveMatch();
this._container.prevActiveMatch();
return;
}

// down
if (e.keyCode === 40) {
this.container.nextActiveMatch();
this._container.nextActiveMatch();
return;
}

// enter
if (e.keyCode === 13) {
this.container.selectActiveMatch();
this._container.selectActiveMatch();
return;
}
}
Expand Down Expand Up @@ -120,15 +129,15 @@ export class TypeaheadDirective implements OnInit {

@HostListener('blur')
public onBlur():void {
if (this.container && !this.container.isFocused) {
if (this._container && !this._container.isFocused) {
this.hide();
}
}

@HostListener('keydown', ['$event'])
public onKeydown(e:KeyboardEvent):void {
// no container - no problems
if (!this.container) {
if (!this._container) {
return;
}

Expand All @@ -146,12 +155,14 @@ export class TypeaheadDirective implements OnInit {
}

public constructor(control:NgControl, viewContainerRef:ViewContainerRef, element:ElementRef,
renderer:Renderer, componentsHelper:ComponentsHelper) {
renderer:Renderer, componentsHelper:ComponentsHelper, cis: ComponentLoaderFactory) {
this.element = element;
this.ngControl = control;
this.viewContainerRef = viewContainerRef;
this.renderer = renderer;
this.componentsHelper = componentsHelper;
// this.componentsHelper = componentsHelper;
this._typeahead = cis
.createLoader<TypeaheadContainerComponent>(element, viewContainerRef, renderer);
}

public ngOnInit():void {
Expand Down Expand Up @@ -187,39 +198,59 @@ export class TypeaheadDirective implements OnInit {
}

public show():void {
let options = new TypeaheadOptions({
typeaheadRef: this,
placement: this.placement,
animation: false
});

let binding = ReflectiveInjector.resolve([
{provide: TypeaheadOptions, useValue: options}
]);

this.popup = this.componentsHelper
.appendNextToLocation(TypeaheadContainerComponent, this.viewContainerRef, binding);

this.popup.instance.position(this.viewContainerRef.element);
this.container = this.popup.instance;
this.container.parent = this;
this._typeahead
.attach(TypeaheadContainerComponent)
// todo: add append to body, after updating positioning service
// .to(this.container)
// .position({attachment: 'bottom left'})
.show(null, {
typeaheadRef: this,
placement: this.placement,
animation: false
});

// let options = new TypeaheadOptions({
// typeaheadRef: this,
// placement: this.placement,
// animation: false
// });
//
// let binding = ReflectiveInjector.resolve([
// {provide: TypeaheadOptions, useValue: options}
// ]);
//
// this.popup = this.componentsHelper
// .appendNextToLocation(TypeaheadContainerComponent, this.viewContainerRef, binding);

// this.popup.instance.position(this.viewContainerRef.element);
// this._container = this.popup.instance;
this._container = this._typeahead.instance;
this._container.parent = this;
// This improves the speed as it won't have to be done for each list item
let normalizedQuery = (this.typeaheadLatinize
? TypeaheadUtils.latinize(this.ngControl.control.value)
: this.ngControl.control.value).toString()
.toLowerCase();
this.container.query = this.typeaheadSingleWords
this._container.query = this.typeaheadSingleWords
? TypeaheadUtils.tokenize(normalizedQuery, this.typeaheadWordDelimiters, this.typeaheadPhraseDelimiters)
: normalizedQuery;
this.container.matches = this._matches;
this._container.matches = this._matches;
this.element.nativeElement.focus();
}

public hide():void {
if (this.container) {
this.popup.destroy();
this.container = void 0;
if (this._typeahead.isShown) {
this._typeahead.hide();
this._container = null;
}
// if (this._container) {
// this.popup.destroy();
// this._container = void 0;
// }
}

public ngOnDestroy():any {
this._typeahead.dispose();
}

protected asyncActions():void {
Expand Down Expand Up @@ -305,16 +336,16 @@ export class TypeaheadDirective implements OnInit {
return;
}

if (this.container) {
if (this._container) {
// This improves the speed as it won't have to be done for each list item
let normalizedQuery = (this.typeaheadLatinize
? TypeaheadUtils.latinize(this.ngControl.control.value)
: this.ngControl.control.value).toString()
.toLowerCase();
this.container.query = this.typeaheadSingleWords
this._container.query = this.typeaheadSingleWords
? TypeaheadUtils.tokenize(normalizedQuery, this.typeaheadWordDelimiters, this.typeaheadPhraseDelimiters)
: normalizedQuery;
this.container.matches = this._matches;
this._container.matches = this._matches;
} else {
this.show();
}
Expand Down
3 changes: 2 additions & 1 deletion src/typeahead/typeahead.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,13 @@ import { FormsModule } from '@angular/forms';
import { TypeaheadContainerComponent } from './typeahead-container.component';
import { TypeaheadDirective } from './typeahead.directive';
import { ComponentsHelper } from '../utils/components-helper.service';
import { ComponentLoaderFactory } from '../component-loader';

@NgModule({
imports: [CommonModule, FormsModule],
declarations: [TypeaheadContainerComponent, TypeaheadDirective],
exports: [FormsModule, TypeaheadContainerComponent, TypeaheadDirective],
providers: [ComponentsHelper],
providers: [ComponentsHelper, ComponentLoaderFactory],
entryComponents: [TypeaheadContainerComponent]
})
export class TypeaheadModule {
Expand Down

0 comments on commit a86c340

Please sign in to comment.