mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-08-21 13:01:01 +08:00
perf(toggle): events are not zoned
This commit is contained in:
@ -1,6 +1,6 @@
|
|||||||
|
|
||||||
import { Toggle } from '../toggle';
|
import { Toggle } from '../toggle';
|
||||||
import { mockConfig, mockPlatform, mockHaptic, mockElementRef, mockGestureController, mockRenderer, mockItem, mockForm, mockChangeDetectorRef } from '../../../util/mock-providers';
|
import { mockConfig, mockPlatform, mockHaptic, mockElementRef, mockGestureController, mockRenderer, mockItem, mockForm, mockChangeDetectorRef, mockZone } from '../../../util/mock-providers';
|
||||||
import { commonInputTest, BOOLEAN_CORPUS } from '../../../util/input-tester';
|
import { commonInputTest, BOOLEAN_CORPUS } from '../../../util/input-tester';
|
||||||
|
|
||||||
describe('Toggle', () => {
|
describe('Toggle', () => {
|
||||||
@ -16,7 +16,8 @@ describe('Toggle', () => {
|
|||||||
const haptic = mockHaptic();
|
const haptic = mockHaptic();
|
||||||
const cd = mockChangeDetectorRef();
|
const cd = mockChangeDetectorRef();
|
||||||
const gesture = mockGestureController();
|
const gesture = mockGestureController();
|
||||||
const toggle = new Toggle(form, config, platform, elementRef, renderer, haptic, item, gesture, null, cd);
|
const zone = mockZone();
|
||||||
|
const toggle = new Toggle(form, config, platform, elementRef, renderer, haptic, item, gesture, null, cd, zone);
|
||||||
|
|
||||||
commonInputTest(toggle, {
|
commonInputTest(toggle, {
|
||||||
defaultValue: false,
|
defaultValue: false,
|
||||||
|
@ -20,7 +20,7 @@ export class ToggleGesture extends PanGesture {
|
|||||||
plt,
|
plt,
|
||||||
toggle.getNativeElement(), {
|
toggle.getNativeElement(), {
|
||||||
threshold: 0,
|
threshold: 0,
|
||||||
zone: true,
|
zone: false,
|
||||||
domController: domCtrl,
|
domController: domCtrl,
|
||||||
gesture: gestureCtrl.createGesture({
|
gesture: gestureCtrl.createGesture({
|
||||||
name: GESTURE_TOGGLE,
|
name: GESTURE_TOGGLE,
|
||||||
|
@ -61,11 +61,11 @@ $toggle-md-item-right-padding: 12px ($item-md-padding-right / 2) 12px
|
|||||||
.toggle-md {
|
.toggle-md {
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|
||||||
|
padding: $toggle-md-padding;
|
||||||
|
|
||||||
width: $toggle-md-track-width;
|
width: $toggle-md-track-width;
|
||||||
height: $toggle-md-track-height;
|
height: $toggle-md-track-height;
|
||||||
|
|
||||||
padding: $toggle-md-padding;
|
|
||||||
|
|
||||||
box-sizing: content-box;
|
box-sizing: content-box;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -107,6 +107,10 @@ $toggle-md-item-right-padding: 12px ($item-md-padding-right / 2) 12px
|
|||||||
|
|
||||||
transition-duration: $toggle-md-transition-duration;
|
transition-duration: $toggle-md-transition-duration;
|
||||||
transition-property: transform, background-color;
|
transition-property: transform, background-color;
|
||||||
|
|
||||||
|
will-change: transform, background-color;
|
||||||
|
|
||||||
|
contain: strict;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { AfterViewInit, ChangeDetectorRef, Component, ElementRef, forwardRef, HostListener, Input, OnDestroy, Optional, Renderer, ViewEncapsulation } from '@angular/core';
|
import { NgZone, AfterViewInit, ChangeDetectorRef, Component, ElementRef, forwardRef, HostListener, Input, OnDestroy, Optional, Renderer, ViewEncapsulation } from '@angular/core';
|
||||||
import { NG_VALUE_ACCESSOR } from '@angular/forms';
|
import { NG_VALUE_ACCESSOR } from '@angular/forms';
|
||||||
|
|
||||||
import { Config } from '../../config/config';
|
import { Config } from '../../config/config';
|
||||||
@ -13,7 +13,6 @@ import { KEY_ENTER, KEY_SPACE } from '../../platform/key';
|
|||||||
import { Platform } from '../../platform/platform';
|
import { Platform } from '../../platform/platform';
|
||||||
import { ToggleGesture } from './toggle-gesture';
|
import { ToggleGesture } from './toggle-gesture';
|
||||||
|
|
||||||
|
|
||||||
export const TOGGLE_VALUE_ACCESSOR: any = {
|
export const TOGGLE_VALUE_ACCESSOR: any = {
|
||||||
provide: NG_VALUE_ACCESSOR,
|
provide: NG_VALUE_ACCESSOR,
|
||||||
useExisting: forwardRef(() => Toggle),
|
useExisting: forwardRef(() => Toggle),
|
||||||
@ -109,7 +108,8 @@ export class Toggle extends BaseInput<boolean> implements IonicTapInput, AfterVi
|
|||||||
@Optional() item: Item,
|
@Optional() item: Item,
|
||||||
private _gestureCtrl: GestureController,
|
private _gestureCtrl: GestureController,
|
||||||
private _domCtrl: DomController,
|
private _domCtrl: DomController,
|
||||||
private _cd: ChangeDetectorRef
|
private _cd: ChangeDetectorRef,
|
||||||
|
private _zone: NgZone,
|
||||||
) {
|
) {
|
||||||
super(config, elementRef, renderer, 'toggle', false, form, item, null);
|
super(config, elementRef, renderer, 'toggle', false, form, item, null);
|
||||||
}
|
}
|
||||||
@ -142,9 +142,11 @@ export class Toggle extends BaseInput<boolean> implements IonicTapInput, AfterVi
|
|||||||
assert(startX, 'startX must be valid');
|
assert(startX, 'startX must be valid');
|
||||||
console.debug('toggle, _onDragStart', startX);
|
console.debug('toggle, _onDragStart', startX);
|
||||||
|
|
||||||
this._startX = startX;
|
this._zone.run(() => {
|
||||||
this._fireFocus();
|
this._startX = startX;
|
||||||
this._activated = true;
|
this._fireFocus();
|
||||||
|
this._activated = true;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -156,22 +158,32 @@ export class Toggle extends BaseInput<boolean> implements IonicTapInput, AfterVi
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
console.debug('toggle, _onDragMove', currentX);
|
let dirty = false;
|
||||||
|
let value: boolean;
|
||||||
|
let activated: boolean;
|
||||||
|
|
||||||
if (this._value) {
|
if (this._value) {
|
||||||
if (currentX + 15 < this._startX) {
|
if (currentX + 15 < this._startX) {
|
||||||
this.value = false;
|
dirty = true;
|
||||||
this._haptic.selection();
|
value = false;
|
||||||
this._startX = currentX;
|
activated = true;
|
||||||
this._activated = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (currentX - 15 > this._startX) {
|
} else if (currentX - 15 > this._startX) {
|
||||||
this.value = true;
|
dirty = true;
|
||||||
this._haptic.selection();
|
value = true;
|
||||||
this._startX = currentX;
|
activated = (currentX < this._startX + 5);
|
||||||
this._activated = (currentX < this._startX + 5);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (dirty) {
|
||||||
|
this._zone.run(() => {
|
||||||
|
this.value = value;
|
||||||
|
this._startX = currentX;
|
||||||
|
this._activated = activated;
|
||||||
|
this._haptic.selection();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -184,20 +196,22 @@ export class Toggle extends BaseInput<boolean> implements IonicTapInput, AfterVi
|
|||||||
}
|
}
|
||||||
console.debug('toggle, _onDragEnd', endX);
|
console.debug('toggle, _onDragEnd', endX);
|
||||||
|
|
||||||
if (this._value) {
|
this._zone.run(() => {
|
||||||
if (this._startX + 4 > endX) {
|
if (this._value) {
|
||||||
this.value = false;
|
if (this._startX + 4 > endX) {
|
||||||
|
this.value = false;
|
||||||
|
this._haptic.selection();
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if (this._startX - 4 < endX) {
|
||||||
|
this.value = true;
|
||||||
this._haptic.selection();
|
this._haptic.selection();
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (this._startX - 4 < endX) {
|
this._activated = false;
|
||||||
this.value = true;
|
this._fireBlur();
|
||||||
this._haptic.selection();
|
this._startX = null;
|
||||||
}
|
});
|
||||||
|
|
||||||
this._activated = false;
|
|
||||||
this._fireBlur();
|
|
||||||
this._startX = null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { ElementRef, EventEmitter, Input, Output, Renderer } from '@angular/core';
|
import { ElementRef, EventEmitter, Input, NgZone, Output, Renderer } from '@angular/core';
|
||||||
import { ControlValueAccessor } from '@angular/forms';
|
import { ControlValueAccessor } from '@angular/forms';
|
||||||
import { NgControl } from '@angular/forms';
|
import { NgControl } from '@angular/forms';
|
||||||
|
|
||||||
@ -130,6 +130,8 @@ export class BaseInput<T> extends Ion implements CommonInput<T> {
|
|||||||
* @hidden
|
* @hidden
|
||||||
*/
|
*/
|
||||||
_writeValue(val: any): boolean {
|
_writeValue(val: any): boolean {
|
||||||
|
assert(NgZone.isInAngularZone(), 'callback should be zoned');
|
||||||
|
|
||||||
if (isUndefined(val)) {
|
if (isUndefined(val)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -154,7 +156,10 @@ export class BaseInput<T> extends Ion implements CommonInput<T> {
|
|||||||
*/
|
*/
|
||||||
_fireIonChange() {
|
_fireIonChange() {
|
||||||
if (this._init) {
|
if (this._init) {
|
||||||
this._debouncer.debounce(() => this.ionChange.emit(this));
|
this._debouncer.debounce(() => {
|
||||||
|
assert(NgZone.isInAngularZone(), 'callback should be zoned');
|
||||||
|
this.ionChange.emit(this);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user