mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-08-20 12:29:55 +08:00
fix(datetime): fixes date time in 3.0 + perf improvements
This commit is contained in:
@ -8,7 +8,7 @@ import { PickerColumn } from '../picker/picker-options';
|
|||||||
import { Form } from '../../util/form';
|
import { Form } from '../../util/form';
|
||||||
import { Ion } from '../ion';
|
import { Ion } from '../ion';
|
||||||
import { Item } from '../item/item';
|
import { Item } from '../item/item';
|
||||||
import { deepCopy, isBlank, isPresent, isTrueProperty, isArray, isString, assert } from '../../util/util';
|
import { deepCopy, isBlank, isPresent, isTrueProperty, isArray, isString, assert, clamp } from '../../util/util';
|
||||||
import { dateValueRange, renderDateTime, renderTextFormat, convertFormatToKey, getValueFromFormat, parseTemplate, parseDate, updateDate, DateTimeData, convertDataToISO, daysInMonth, dateSortValue, dateDataSortValue, LocaleData } from '../../util/datetime-util';
|
import { dateValueRange, renderDateTime, renderTextFormat, convertFormatToKey, getValueFromFormat, parseTemplate, parseDate, updateDate, DateTimeData, convertDataToISO, daysInMonth, dateSortValue, dateDataSortValue, LocaleData } from '../../util/datetime-util';
|
||||||
|
|
||||||
export const DATETIME_VALUE_ACCESSOR: any = {
|
export const DATETIME_VALUE_ACCESSOR: any = {
|
||||||
@ -514,14 +514,12 @@ export class DateTime extends Ion implements AfterContentInit, ControlValueAcces
|
|||||||
picker.refresh();
|
picker.refresh();
|
||||||
});
|
});
|
||||||
|
|
||||||
picker.present(pickerOptions);
|
|
||||||
|
|
||||||
this._isOpen = true;
|
this._isOpen = true;
|
||||||
picker.onDidDismiss(() => {
|
picker.onDidDismiss(() => {
|
||||||
this._isOpen = false;
|
this._isOpen = false;
|
||||||
});
|
});
|
||||||
|
|
||||||
picker.refresh();
|
picker.present(pickerOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -565,7 +563,7 @@ export class DateTime extends Ion implements AfterContentInit, ControlValueAcces
|
|||||||
values = dateValueRange(format, this._min, this._max);
|
values = dateValueRange(format, this._min, this._max);
|
||||||
}
|
}
|
||||||
|
|
||||||
let column: PickerColumn = {
|
const column: PickerColumn = {
|
||||||
name: key,
|
name: key,
|
||||||
selectedIndex: 0,
|
selectedIndex: 0,
|
||||||
options: values.map(val => {
|
options: values.map(val => {
|
||||||
@ -578,8 +576,8 @@ export class DateTime extends Ion implements AfterContentInit, ControlValueAcces
|
|||||||
|
|
||||||
// cool, we've loaded up the columns with options
|
// cool, we've loaded up the columns with options
|
||||||
// preselect the option for this column
|
// preselect the option for this column
|
||||||
var optValue = getValueFromFormat(this._value, format);
|
const optValue = getValueFromFormat(this._value, format);
|
||||||
var selectedIndex = column.options.findIndex(opt => opt.value === optValue);
|
const selectedIndex = column.options.findIndex(opt => opt.value === optValue);
|
||||||
if (selectedIndex >= 0) {
|
if (selectedIndex >= 0) {
|
||||||
// set the select index for this column's options
|
// set the select index for this column's options
|
||||||
column.selectedIndex = selectedIndex;
|
column.selectedIndex = selectedIndex;
|
||||||
@ -589,10 +587,10 @@ export class DateTime extends Ion implements AfterContentInit, ControlValueAcces
|
|||||||
picker.addColumn(column);
|
picker.addColumn(column);
|
||||||
});
|
});
|
||||||
|
|
||||||
const min = <any>this._min;
|
|
||||||
const max = <any>this._max;
|
|
||||||
|
|
||||||
// Normalize min/max
|
// Normalize min/max
|
||||||
|
const min = <any>this._min;
|
||||||
|
const max = <any>this._max;
|
||||||
const columns = this._picker.getColumns();
|
const columns = this._picker.getColumns();
|
||||||
['month', 'day', 'hour', 'minute']
|
['month', 'day', 'hour', 'minute']
|
||||||
.filter(name => !columns.find(column => column.name === name))
|
.filter(name => !columns.find(column => column.name === name))
|
||||||
@ -620,6 +618,8 @@ export class DateTime extends Ion implements AfterContentInit, ControlValueAcces
|
|||||||
const lb = lowerBounds.slice();
|
const lb = lowerBounds.slice();
|
||||||
const ub = upperBounds.slice();
|
const ub = upperBounds.slice();
|
||||||
const options = column.options;
|
const options = column.options;
|
||||||
|
let indexMin = options.length - 1;
|
||||||
|
let indexMax = 0;
|
||||||
|
|
||||||
for (var i = 0; i < options.length; i++) {
|
for (var i = 0; i < options.length; i++) {
|
||||||
var opt = options[i];
|
var opt = options[i];
|
||||||
@ -627,15 +627,19 @@ export class DateTime extends Ion implements AfterContentInit, ControlValueAcces
|
|||||||
lb[index] = opt.value;
|
lb[index] = opt.value;
|
||||||
ub[index] = opt.value;
|
ub[index] = opt.value;
|
||||||
|
|
||||||
opt.disabled = (
|
var disabled = opt.disabled = (
|
||||||
value < lowerBounds[index] ||
|
value < lowerBounds[index] ||
|
||||||
value > upperBounds[index] ||
|
value > upperBounds[index] ||
|
||||||
dateSortValue(ub[0], ub[1], ub[2], ub[3], ub[4]) < min ||
|
dateSortValue(ub[0], ub[1], ub[2], ub[3], ub[4]) < min ||
|
||||||
dateSortValue(lb[0], lb[1], lb[2], lb[3], lb[4]) > max
|
dateSortValue(lb[0], lb[1], lb[2], lb[3], lb[4]) > max
|
||||||
);
|
);
|
||||||
|
if (!disabled) {
|
||||||
|
indexMin = Math.min(indexMin, i);
|
||||||
|
indexMax = Math.max(indexMax, i);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
let selectedIndex = column.selectedIndex = clamp(indexMin, column.selectedIndex, indexMax);
|
||||||
opt = column.options[column.selectedIndex];
|
opt = column.options[selectedIndex];
|
||||||
if (opt) {
|
if (opt) {
|
||||||
return opt.value;
|
return opt.value;
|
||||||
}
|
}
|
||||||
|
@ -104,5 +104,15 @@
|
|||||||
></ion-datetime>
|
></ion-datetime>
|
||||||
</ion-item>
|
</ion-item>
|
||||||
|
|
||||||
|
<ion-item>
|
||||||
|
<ion-label>Current year Date</ion-label>
|
||||||
|
<ion-datetime min="2017-03-20"></ion-datetime>
|
||||||
|
</ion-item>
|
||||||
|
|
||||||
|
<ion-item>
|
||||||
|
<ion-label>Last year Date</ion-label>
|
||||||
|
<ion-datetime min="2016-03-20"></ion-datetime>
|
||||||
|
</ion-item>
|
||||||
|
|
||||||
|
|
||||||
</ion-content>
|
</ion-content>
|
||||||
|
@ -78,9 +78,6 @@ export class PickerColumnCmp {
|
|||||||
// get the height of one option
|
// get the height of one option
|
||||||
this.optHeight = (colEle.firstElementChild ? colEle.firstElementChild.clientHeight : 0);
|
this.optHeight = (colEle.firstElementChild ? colEle.firstElementChild.clientHeight : 0);
|
||||||
|
|
||||||
// set the scroll position for the selected option
|
|
||||||
this.setSelected(this.col.selectedIndex, 0);
|
|
||||||
|
|
||||||
// Listening for pointer events
|
// Listening for pointer events
|
||||||
this.events.pointerEvents({
|
this.events.pointerEvents({
|
||||||
element: this.elementRef.nativeElement,
|
element: this.elementRef.nativeElement,
|
||||||
@ -384,6 +381,7 @@ export class PickerColumnCmp {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
this.col.prevSelected = selectedIndex;
|
||||||
|
|
||||||
if (saveY) {
|
if (saveY) {
|
||||||
this.y = y;
|
this.y = y;
|
||||||
@ -409,19 +407,20 @@ export class PickerColumnCmp {
|
|||||||
refresh() {
|
refresh() {
|
||||||
let min = this.col.options.length - 1;
|
let min = this.col.options.length - 1;
|
||||||
let max = 0;
|
let max = 0;
|
||||||
|
const options = this.col.options;
|
||||||
for (var i = 0; i < this.col.options.length; i++) {
|
for (var i = 0; i < options.length; i++) {
|
||||||
if (!this.col.options[i].disabled) {
|
if (!options[i].disabled) {
|
||||||
min = Math.min(min, i);
|
min = Math.min(min, i);
|
||||||
max = Math.max(max, i);
|
max = Math.max(max, i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var selectedIndex = clamp(min, this.col.selectedIndex, max);
|
const selectedIndex = clamp(min, this.col.selectedIndex, max);
|
||||||
|
if (this.col.prevSelected !== selectedIndex) {
|
||||||
if (selectedIndex !== this.col.selectedIndex) {
|
|
||||||
var y = (selectedIndex * this.optHeight) * -1;
|
var y = (selectedIndex * this.optHeight) * -1;
|
||||||
this.update(y, 150, true, true);
|
this._plt.cancelRaf(this.rafId);
|
||||||
|
this.velocity = 0;
|
||||||
|
this.update(y, 150, true, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -40,6 +40,7 @@ import { PickerColumnCmp } from './picker-column';
|
|||||||
encapsulation: ViewEncapsulation.None,
|
encapsulation: ViewEncapsulation.None,
|
||||||
})
|
})
|
||||||
export class PickerCmp {
|
export class PickerCmp {
|
||||||
|
|
||||||
@ViewChildren(PickerColumnCmp) _cols: QueryList<PickerColumnCmp>;
|
@ViewChildren(PickerColumnCmp) _cols: QueryList<PickerColumnCmp>;
|
||||||
d: PickerOptions;
|
d: PickerOptions;
|
||||||
enabled: boolean;
|
enabled: boolean;
|
||||||
@ -116,6 +117,10 @@ export class PickerCmp {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ionViewDidLoad() {
|
||||||
|
this.refresh();
|
||||||
|
}
|
||||||
|
|
||||||
ionViewWillEnter() {
|
ionViewWillEnter() {
|
||||||
this._gestureBlocker.block();
|
this._gestureBlocker.block();
|
||||||
}
|
}
|
||||||
@ -125,9 +130,7 @@ export class PickerCmp {
|
|||||||
}
|
}
|
||||||
|
|
||||||
refresh() {
|
refresh() {
|
||||||
this._cols.forEach(column => {
|
this._cols.forEach(column => column.refresh());
|
||||||
column.refresh();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_colChange(selectedOption: PickerColumnOption) {
|
_colChange(selectedOption: PickerColumnOption) {
|
||||||
|
@ -10,6 +10,7 @@ export interface PickerColumn {
|
|||||||
name?: string;
|
name?: string;
|
||||||
align?: string;
|
align?: string;
|
||||||
selectedIndex?: number;
|
selectedIndex?: number;
|
||||||
|
prevSelected?: number;
|
||||||
prefix?: string;
|
prefix?: string;
|
||||||
suffix?: string;
|
suffix?: string;
|
||||||
options?: PickerColumnOption[];
|
options?: PickerColumnOption[];
|
||||||
|
@ -2,7 +2,7 @@ import { EventEmitter, Output } from '@angular/core';
|
|||||||
|
|
||||||
import { App } from '../app/app';
|
import { App } from '../app/app';
|
||||||
import { Config } from '../../config/config';
|
import { Config } from '../../config/config';
|
||||||
import { isPresent } from '../../util/util';
|
import { isPresent, assert } from '../../util/util';
|
||||||
import { NavOptions } from '../../navigation/nav-util';
|
import { NavOptions } from '../../navigation/nav-util';
|
||||||
import { PickerCmp } from './picker-component';
|
import { PickerCmp } from './picker-component';
|
||||||
import { PickerOptions, PickerColumn } from './picker-options';
|
import { PickerOptions, PickerColumn } from './picker-options';
|
||||||
@ -67,6 +67,9 @@ export class Picker extends ViewController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
refresh() {
|
refresh() {
|
||||||
|
assert(this._cmp, 'componentRef must be valid');
|
||||||
|
assert(this._cmp.instance.refresh, 'instance must implement refresh()');
|
||||||
|
|
||||||
this._cmp && this._cmp.instance.refresh && this._cmp.instance.refresh();
|
this._cmp && this._cmp.instance.refresh && this._cmp.instance.refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -517,6 +517,7 @@ export class NavControllerBase extends Ion implements NavController {
|
|||||||
|
|
||||||
_viewAttachToDOM(view: ViewController, componentRef: ComponentRef<any>, viewport: ViewContainerRef) {
|
_viewAttachToDOM(view: ViewController, componentRef: ComponentRef<any>, viewport: ViewContainerRef) {
|
||||||
assert(view._state === STATE_INITIALIZED, 'view state must be INITIALIZED');
|
assert(view._state === STATE_INITIALIZED, 'view state must be INITIALIZED');
|
||||||
|
assert(componentRef, 'componentRef can not be null');
|
||||||
|
|
||||||
// fire willLoad before change detection runs
|
// fire willLoad before change detection runs
|
||||||
this._willLoad(view);
|
this._willLoad(view);
|
||||||
|
@ -116,6 +116,8 @@ export class ViewController {
|
|||||||
* @hidden
|
* @hidden
|
||||||
*/
|
*/
|
||||||
init(componentRef: ComponentRef<any>) {
|
init(componentRef: ComponentRef<any>) {
|
||||||
|
assert(componentRef, 'componentRef can not be null');
|
||||||
|
|
||||||
this._cmp = componentRef;
|
this._cmp = componentRef;
|
||||||
this.instance = this.instance || componentRef.instance;
|
this.instance = this.instance || componentRef.instance;
|
||||||
this._detached = false;
|
this._detached = false;
|
||||||
|
Reference in New Issue
Block a user