Skip to content

Commit 99142f8

Browse files
committed
fix(datetime): fixes date time in 3.0 + perf improvements
1 parent 02f8f11 commit 99142f8

File tree

8 files changed

+49
-26
lines changed

8 files changed

+49
-26
lines changed

src/components/datetime/datetime.ts

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import { PickerColumn } from '../picker/picker-options';
88
import { Form } from '../../util/form';
99
import { Ion } from '../ion';
1010
import { Item } from '../item/item';
11-
import { deepCopy, isBlank, isPresent, isTrueProperty, isArray, isString, assert } from '../../util/util';
11+
import { deepCopy, isBlank, isPresent, isTrueProperty, isArray, isString, assert, clamp } from '../../util/util';
1212
import { dateValueRange, renderDateTime, renderTextFormat, convertFormatToKey, getValueFromFormat, parseTemplate, parseDate, updateDate, DateTimeData, convertDataToISO, daysInMonth, dateSortValue, dateDataSortValue, LocaleData } from '../../util/datetime-util';
1313

1414
export const DATETIME_VALUE_ACCESSOR: any = {
@@ -514,14 +514,12 @@ export class DateTime extends Ion implements AfterContentInit, ControlValueAcces
514514
picker.refresh();
515515
});
516516

517-
picker.present(pickerOptions);
518-
519517
this._isOpen = true;
520518
picker.onDidDismiss(() => {
521519
this._isOpen = false;
522520
});
523521

524-
picker.refresh();
522+
picker.present(pickerOptions);
525523
}
526524

527525
/**
@@ -565,7 +563,7 @@ export class DateTime extends Ion implements AfterContentInit, ControlValueAcces
565563
values = dateValueRange(format, this._min, this._max);
566564
}
567565

568-
let column: PickerColumn = {
566+
const column: PickerColumn = {
569567
name: key,
570568
selectedIndex: 0,
571569
options: values.map(val => {
@@ -578,8 +576,8 @@ export class DateTime extends Ion implements AfterContentInit, ControlValueAcces
578576

579577
// cool, we've loaded up the columns with options
580578
// preselect the option for this column
581-
var optValue = getValueFromFormat(this._value, format);
582-
var selectedIndex = column.options.findIndex(opt => opt.value === optValue);
579+
const optValue = getValueFromFormat(this._value, format);
580+
const selectedIndex = column.options.findIndex(opt => opt.value === optValue);
583581
if (selectedIndex >= 0) {
584582
// set the select index for this column's options
585583
column.selectedIndex = selectedIndex;
@@ -589,10 +587,10 @@ export class DateTime extends Ion implements AfterContentInit, ControlValueAcces
589587
picker.addColumn(column);
590588
});
591589

592-
const min = <any>this._min;
593-
const max = <any>this._max;
594590

595591
// Normalize min/max
592+
const min = <any>this._min;
593+
const max = <any>this._max;
596594
const columns = this._picker.getColumns();
597595
['month', 'day', 'hour', 'minute']
598596
.filter(name => !columns.find(column => column.name === name))
@@ -620,22 +618,28 @@ export class DateTime extends Ion implements AfterContentInit, ControlValueAcces
620618
const lb = lowerBounds.slice();
621619
const ub = upperBounds.slice();
622620
const options = column.options;
621+
let indexMin = options.length - 1;
622+
let indexMax = 0;
623623

624624
for (var i = 0; i < options.length; i++) {
625625
var opt = options[i];
626626
var value = opt.value;
627627
lb[index] = opt.value;
628628
ub[index] = opt.value;
629629

630-
opt.disabled = (
630+
var disabled = opt.disabled = (
631631
value < lowerBounds[index] ||
632632
value > upperBounds[index] ||
633633
dateSortValue(ub[0], ub[1], ub[2], ub[3], ub[4]) < min ||
634634
dateSortValue(lb[0], lb[1], lb[2], lb[3], lb[4]) > max
635635
);
636+
if (!disabled) {
637+
indexMin = Math.min(indexMin, i);
638+
indexMax = Math.max(indexMax, i);
639+
}
636640
}
637-
638-
opt = column.options[column.selectedIndex];
641+
let selectedIndex = column.selectedIndex = clamp(indexMin, column.selectedIndex, indexMax);
642+
opt = column.options[selectedIndex];
639643
if (opt) {
640644
return opt.value;
641645
}

src/components/datetime/test/issues/pages/root-page/root-page.html

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,5 +104,15 @@
104104
></ion-datetime>
105105
</ion-item>
106106

107+
<ion-item>
108+
<ion-label>Current year Date</ion-label>
109+
<ion-datetime min="2017-03-20"></ion-datetime>
110+
</ion-item>
111+
112+
<ion-item>
113+
<ion-label>Last year Date</ion-label>
114+
<ion-datetime min="2016-03-20"></ion-datetime>
115+
</ion-item>
116+
107117

108118
</ion-content>

src/components/picker/picker-column.ts

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -78,9 +78,6 @@ export class PickerColumnCmp {
7878
// get the height of one option
7979
this.optHeight = (colEle.firstElementChild ? colEle.firstElementChild.clientHeight : 0);
8080

81-
// set the scroll position for the selected option
82-
this.setSelected(this.col.selectedIndex, 0);
83-
8481
// Listening for pointer events
8582
this.events.pointerEvents({
8683
element: this.elementRef.nativeElement,
@@ -384,6 +381,7 @@ export class PickerColumnCmp {
384381
}
385382
}
386383
}
384+
this.col.prevSelected = selectedIndex;
387385

388386
if (saveY) {
389387
this.y = y;
@@ -409,19 +407,20 @@ export class PickerColumnCmp {
409407
refresh() {
410408
let min = this.col.options.length - 1;
411409
let max = 0;
412-
413-
for (var i = 0; i < this.col.options.length; i++) {
414-
if (!this.col.options[i].disabled) {
410+
const options = this.col.options;
411+
for (var i = 0; i < options.length; i++) {
412+
if (!options[i].disabled) {
415413
min = Math.min(min, i);
416414
max = Math.max(max, i);
417415
}
418416
}
419417

420-
var selectedIndex = clamp(min, this.col.selectedIndex, max);
421-
422-
if (selectedIndex !== this.col.selectedIndex) {
418+
const selectedIndex = clamp(min, this.col.selectedIndex, max);
419+
if (this.col.prevSelected !== selectedIndex) {
423420
var y = (selectedIndex * this.optHeight) * -1;
424-
this.update(y, 150, true, true);
421+
this._plt.cancelRaf(this.rafId);
422+
this.velocity = 0;
423+
this.update(y, 150, true, false);
425424
}
426425
}
427426

src/components/picker/picker-component.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ import { PickerColumnCmp } from './picker-column';
4040
encapsulation: ViewEncapsulation.None,
4141
})
4242
export class PickerCmp {
43+
4344
@ViewChildren(PickerColumnCmp) _cols: QueryList<PickerColumnCmp>;
4445
d: PickerOptions;
4546
enabled: boolean;
@@ -116,6 +117,10 @@ export class PickerCmp {
116117
});
117118
}
118119

120+
ionViewDidLoad() {
121+
this.refresh();
122+
}
123+
119124
ionViewWillEnter() {
120125
this._gestureBlocker.block();
121126
}
@@ -125,9 +130,7 @@ export class PickerCmp {
125130
}
126131

127132
refresh() {
128-
this._cols.forEach(column => {
129-
column.refresh();
130-
});
133+
this._cols.forEach(column => column.refresh());
131134
}
132135

133136
_colChange(selectedOption: PickerColumnOption) {

src/components/picker/picker-options.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ export interface PickerColumn {
1010
name?: string;
1111
align?: string;
1212
selectedIndex?: number;
13+
prevSelected?: number;
1314
prefix?: string;
1415
suffix?: string;
1516
options?: PickerColumnOption[];

src/components/picker/picker.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { EventEmitter, Output } from '@angular/core';
22

33
import { App } from '../app/app';
44
import { Config } from '../../config/config';
5-
import { isPresent } from '../../util/util';
5+
import { isPresent, assert } from '../../util/util';
66
import { NavOptions } from '../../navigation/nav-util';
77
import { PickerCmp } from './picker-component';
88
import { PickerOptions, PickerColumn } from './picker-options';
@@ -67,6 +67,9 @@ export class Picker extends ViewController {
6767
}
6868

6969
refresh() {
70+
assert(this._cmp, 'componentRef must be valid');
71+
assert(this._cmp.instance.refresh, 'instance must implement refresh()');
72+
7073
this._cmp && this._cmp.instance.refresh && this._cmp.instance.refresh();
7174
}
7275

src/navigation/nav-controller-base.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -517,6 +517,7 @@ export class NavControllerBase extends Ion implements NavController {
517517

518518
_viewAttachToDOM(view: ViewController, componentRef: ComponentRef<any>, viewport: ViewContainerRef) {
519519
assert(view._state === STATE_INITIALIZED, 'view state must be INITIALIZED');
520+
assert(componentRef, 'componentRef can not be null');
520521

521522
// fire willLoad before change detection runs
522523
this._willLoad(view);

src/navigation/view-controller.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,8 @@ export class ViewController {
116116
* @hidden
117117
*/
118118
init(componentRef: ComponentRef<any>) {
119+
assert(componentRef, 'componentRef can not be null');
120+
119121
this._cmp = componentRef;
120122
this.instance = this.instance || componentRef.instance;
121123
this._detached = false;

0 commit comments

Comments
 (0)