Skip to content

Commit 0e9b291

Browse files
authored
fix(timepicker): display correct NgModel value inside OnPush component (#3001)
Fixes #2992
1 parent a613fa9 commit 0e9b291

File tree

2 files changed

+40
-8
lines changed

2 files changed

+40
-8
lines changed

src/timepicker/timepicker.spec.ts

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
import {TestBed, ComponentFixture, async, inject} from '@angular/core/testing';
1+
import {async, ComponentFixture, inject, TestBed} from '@angular/core/testing';
22
import {createGenericTestComponent} from '../test/common';
33

4-
import {Component, Injectable} from '@angular/core';
4+
import {ChangeDetectionStrategy, Component, Injectable} from '@angular/core';
55
import {By} from '@angular/platform-browser';
6-
import {Validators, FormControl, FormGroup, FormsModule, ReactiveFormsModule} from '@angular/forms';
6+
import {FormControl, FormGroup, FormsModule, ReactiveFormsModule, Validators} from '@angular/forms';
77

88
import {NgbTimepickerModule} from './timepicker.module';
99
import {NgbTimepickerConfig} from './timepicker-config';
@@ -14,6 +14,9 @@ import {NgbTimeStruct} from './ngb-time-struct';
1414
const createTestComponent = (html: string) =>
1515
createGenericTestComponent(html, TestComponent) as ComponentFixture<TestComponent>;
1616

17+
const createOnPushTestComponent = (html: string) =>
18+
createGenericTestComponent(html, TestComponentOnPush) as ComponentFixture<TestComponentOnPush>;
19+
1720
function getTimepicker(el: HTMLElement) {
1821
return el.querySelector('ngb-timepicker');
1922
}
@@ -78,14 +81,16 @@ function customizeConfig(config: NgbTimepickerConfig) {
7881
describe('ngb-timepicker', () => {
7982

8083
beforeEach(() => {
81-
TestBed.configureTestingModule(
82-
{declarations: [TestComponent], imports: [NgbTimepickerModule, FormsModule, ReactiveFormsModule]});
84+
TestBed.configureTestingModule({
85+
declarations: [TestComponent, TestComponentOnPush],
86+
imports: [NgbTimepickerModule, FormsModule, ReactiveFormsModule]
87+
});
8388
});
8489

8590
describe('initialization', () => {
8691
it('should initialize inputs with provided config', () => {
8792
const defaultConfig = new NgbTimepickerConfig();
88-
const timepicker = new NgbTimepicker(new NgbTimepickerConfig(), new NgbTimeStructAdapter());
93+
const timepicker = new NgbTimepicker(new NgbTimepickerConfig(), new NgbTimeStructAdapter(), null);
8994
expectSameValues(timepicker, defaultConfig);
9095
});
9196
});
@@ -1532,6 +1537,18 @@ describe('ngb-timepicker', () => {
15321537
});
15331538
});
15341539
});
1540+
1541+
describe('on push', () => {
1542+
1543+
it('should render initial model value', async(async() => {
1544+
const fixture =
1545+
createOnPushTestComponent(`<ngb-timepicker [ngModel]="{hour: 13, minute: 30}"></ngb-timepicker>`);
1546+
fixture.detectChanges();
1547+
await fixture.whenStable();
1548+
fixture.detectChanges();
1549+
expectToDisplayTime(fixture.nativeElement, '13:30');
1550+
}));
1551+
});
15351552
});
15361553

15371554

@@ -1549,6 +1566,10 @@ class TestComponent {
15491566
onSubmit() { this.submitted = true; }
15501567
}
15511568

1569+
@Component({selector: 'test-cmp-on-push', template: '', changeDetection: ChangeDetectionStrategy.OnPush})
1570+
class TestComponentOnPush {
1571+
}
1572+
15521573
@Injectable()
15531574
class StringTimeAdapter extends NgbTimeAdapter<string> {
15541575
fromModel(value: string): NgbTimeStruct {

src/timepicker/timepicker.ts

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,12 @@
1-
import {Component, forwardRef, Input, OnChanges, SimpleChanges, ViewEncapsulation} from '@angular/core';
1+
import {
2+
ChangeDetectorRef,
3+
Component,
4+
forwardRef,
5+
Input,
6+
OnChanges,
7+
SimpleChanges,
8+
ViewEncapsulation
9+
} from '@angular/core';
210
import {ControlValueAccessor, NG_VALUE_ACCESSOR} from '@angular/forms';
311

412
import {isInteger, isNumber, padNumber, toInteger} from '../util/util';
@@ -156,7 +164,9 @@ export class NgbTimepicker implements ControlValueAccessor,
156164
*/
157165
@Input() size: 'small' | 'medium' | 'large';
158166

159-
constructor(private readonly _config: NgbTimepickerConfig, private _ngbTimeAdapter: NgbTimeAdapter<any>) {
167+
constructor(
168+
private readonly _config: NgbTimepickerConfig, private _ngbTimeAdapter: NgbTimeAdapter<any>,
169+
private _cd: ChangeDetectorRef) {
160170
this.meridian = _config.meridian;
161171
this.spinners = _config.spinners;
162172
this.seconds = _config.seconds;
@@ -177,6 +187,7 @@ export class NgbTimepicker implements ControlValueAccessor,
177187
if (!this.seconds && (!structValue || !isNumber(structValue.second))) {
178188
this.model.second = 0;
179189
}
190+
this._cd.markForCheck();
180191
}
181192

182193
registerOnChange(fn: (value: any) => any): void { this.onChange = fn; }

0 commit comments

Comments
 (0)