Skip to content

Commit

Permalink
fix(typeahead): properly handle components using OnPush strategy
Browse files Browse the repository at this point in the history
Fixes #775
  • Loading branch information
pkozlowski-opensource committed Sep 23, 2016
1 parent 7d4a455 commit a2ba68a
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 4 deletions.
32 changes: 28 additions & 4 deletions src/typeahead/typeahead.spec.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import {TestBed, ComponentFixture, async, inject} from '@angular/core/testing';
import {TestBed, ComponentFixture, async, fakeAsync, inject, tick} from '@angular/core/testing';
import {createGenericTestComponent, isBrowser} from '../test/common';
import {expectResults, getWindowLinks} from '../test/typeahead/common';

import {Component, DebugElement, ViewChild} from '@angular/core';
import {Component, DebugElement, ViewChild, ChangeDetectionStrategy} from '@angular/core';
import {Validators, FormControl, FormGroup, FormsModule, ReactiveFormsModule} from '@angular/forms';
import {By} from '@angular/platform-browser';
import {Observable} from 'rxjs/Rx';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/debounceTime';

import {NgbTypeahead} from './typeahead';
import {NgbTypeaheadModule} from './typeahead.module';
Expand All @@ -15,6 +16,9 @@ import {NgbTypeaheadConfig} from './typeahead-config';
const createTestComponent = (html: string) =>
createGenericTestComponent(html, TestComponent) as ComponentFixture<TestComponent>;

const createOnPushTestComponent = (html: string) =>
createGenericTestComponent(html, TestOnPushComponent) as ComponentFixture<TestOnPushComponent>;

enum Key {
Tab = 9,
Enter = 13,
Expand Down Expand Up @@ -62,8 +66,10 @@ function expectWindowResults(element, expectedResults: string[]) {
describe('ngb-typeahead', () => {

beforeEach(() => {
TestBed.configureTestingModule(
{declarations: [TestComponent], imports: [NgbTypeaheadModule, FormsModule, ReactiveFormsModule]});
TestBed.configureTestingModule({
declarations: [TestComponent, TestOnPushComponent],
imports: [NgbTypeaheadModule, FormsModule, ReactiveFormsModule]
});
});

describe('valueaccessor', () => {
Expand Down Expand Up @@ -290,6 +296,15 @@ describe('ngb-typeahead', () => {
expectWindowResults(compiled, ['+ONE', 'ONE MORE']);
});

it('should properly display results when an owning components using OnPush strategy', fakeAsync(() => {
const fixture = createOnPushTestComponent(`<input type="text" [(ngModel)]="model" [ngbTypeahead]="find"/>`);
const compiled = fixture.nativeElement;

changeInput(compiled, 'o');
fixture.detectChanges();
tick(250);
expectWindowResults(compiled, ['+one', 'one more']);
}));
});

describe('objects', () => {
Expand Down Expand Up @@ -588,3 +603,12 @@ class TestComponent {

onSelect($event) { this.selectEventValue = $event; }
}

@Component({selector: 'test-onpush-cmp', changeDetection: ChangeDetectionStrategy.OnPush, template: ''})
class TestOnPushComponent {
private _strings = ['one', 'one more', 'two', 'three'];

find = (text$: Observable<string>) => {
return text$.debounceTime(200).map(text => this._strings.filter(v => v.startsWith(text)));
};
}
5 changes: 5 additions & 0 deletions src/typeahead/typeahead.ts
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,11 @@ export class NgbTypeahead implements ControlValueAccessor,
this._windowRef.instance.resultTemplate = this.resultTemplate;
}
this._showHint();

// The observable stream we are subscribing to might have async steps
// and if a component containing typeahead is using the OnPush strategy
// the change detection turn wouldn't be invoked automatically.
this._windowRef.changeDetectorRef.detectChanges();
}
});
}
Expand Down

0 comments on commit a2ba68a

Please sign in to comment.