mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-08-22 13:32:54 +08:00
fix(refresher): adjust location after layout updates
This commit is contained in:
@ -64,8 +64,6 @@ export class Content extends Ion {
|
||||
private _paddingRight: number;
|
||||
private _paddingBottom: number;
|
||||
private _paddingLeft: number;
|
||||
private _lastTop: number;
|
||||
private _lastBottom: number;
|
||||
private _scrollPadding: number;
|
||||
private _headerHeight: number;
|
||||
private _footerHeight: number;
|
||||
@ -78,6 +76,16 @@ export class Content extends Ion {
|
||||
private _sbPadding: boolean;
|
||||
private _fullscreen: boolean;
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
adjustedTop: number;
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
adjustedBottom: number;
|
||||
|
||||
constructor(
|
||||
private _elementRef: ElementRef,
|
||||
private _config: Config,
|
||||
@ -510,16 +518,18 @@ export class Content extends Ion {
|
||||
if (this._tabbarPlacement === 'top') {
|
||||
newVal += this._tabbarHeight;
|
||||
}
|
||||
if (newVal !== this._lastTop) {
|
||||
if (newVal !== this.adjustedTop) {
|
||||
this._scrollEle.style.paddingTop = (newVal > 0 ? newVal + 'px' : '');
|
||||
this.adjustedTop = newVal;
|
||||
}
|
||||
|
||||
newVal = this._footerHeight + this._paddingBottom;
|
||||
if (this._tabbarPlacement === 'bottom') {
|
||||
newVal += this._tabbarHeight;
|
||||
}
|
||||
if (newVal !== this._lastBottom) {
|
||||
if (newVal !== this.adjustedBottom) {
|
||||
this._scrollEle.style.paddingBottom = (newVal > 0 ? newVal + 'px' : '');
|
||||
this.adjustedBottom = newVal;
|
||||
}
|
||||
|
||||
} else {
|
||||
@ -528,16 +538,18 @@ export class Content extends Ion {
|
||||
if (this._tabbarPlacement === 'top') {
|
||||
newVal += this._tabbarHeight;
|
||||
}
|
||||
if (newVal !== this._lastTop) {
|
||||
if (newVal !== this.adjustedTop) {
|
||||
this._scrollEle.style.marginTop = (newVal > 0 ? newVal + 'px' : '');
|
||||
this.adjustedTop = newVal;
|
||||
}
|
||||
|
||||
newVal = this._footerHeight;
|
||||
if (this._tabbarPlacement === 'bottom') {
|
||||
newVal += this._tabbarHeight;
|
||||
}
|
||||
if (newVal !== this._lastBottom) {
|
||||
if (newVal !== this.adjustedBottom) {
|
||||
this._scrollEle.style.marginBottom = (newVal > 0 ? newVal + 'px' : '');
|
||||
this.adjustedBottom = newVal;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,10 +1,9 @@
|
||||
import {Directive, ElementRef, EventEmitter, Host, Input, Output, NgZone} from '@angular/core';
|
||||
import { Directive, EventEmitter, Host, Input, Output, NgZone } from '@angular/core';
|
||||
|
||||
import {Content} from '../content/content';
|
||||
import {Icon} from '../icon/icon';
|
||||
import {isTrueProperty} from '../../util/util';
|
||||
import {CSS, pointerCoord, transitionEnd} from '../../util/dom';
|
||||
import {PointerEvents, UIEventManager} from '../../util/ui-event-manager';
|
||||
import { Content } from '../content/content';
|
||||
import { CSS, pointerCoord } from '../../util/dom';
|
||||
import { isTrueProperty } from '../../util/util';
|
||||
import { PointerEvents, UIEventManager } from '../../util/ui-event-manager';
|
||||
|
||||
|
||||
/**
|
||||
@ -90,7 +89,8 @@ import {PointerEvents, UIEventManager} from '../../util/ui-event-manager';
|
||||
@Directive({
|
||||
selector: 'ion-refresher',
|
||||
host: {
|
||||
'[class.refresher-active]': 'state !== "inactive"'
|
||||
'[class.refresher-active]': 'state !== "inactive"',
|
||||
'[style.top]': '_top'
|
||||
}
|
||||
})
|
||||
export class Refresher {
|
||||
@ -100,6 +100,7 @@ export class Refresher {
|
||||
private _isEnabled: boolean = true;
|
||||
private _events: UIEventManager = new UIEventManager(false);
|
||||
private _pointerEvents: PointerEvents;
|
||||
private _top: string = '';
|
||||
|
||||
/**
|
||||
* The current state which the refresher is in. The refresher's states include:
|
||||
@ -195,23 +196,8 @@ export class Refresher {
|
||||
@Output() ionStart: EventEmitter<Refresher> = new EventEmitter();
|
||||
|
||||
|
||||
constructor(
|
||||
@Host() private _content: Content,
|
||||
private _zone: NgZone,
|
||||
elementRef: ElementRef) {
|
||||
constructor(@Host() private _content: Content, private _zone: NgZone) {
|
||||
_content.addCssClass('has-refresher');
|
||||
|
||||
// deprecated warning
|
||||
let ele = elementRef.nativeElement;
|
||||
let deprecatedAttrs = ['pullingIcon', 'pullingText', 'refreshingIcon', 'refreshingText', 'spinner'];
|
||||
deprecatedAttrs.forEach(attrName => {
|
||||
if (ele.hasAttribute(attrName)) {
|
||||
console.warn('<ion-refresher> property "' + attrName + '" should now be placed on the inner <ion-refresher-content> component instead of <ion-refresher>. Please review the Refresher docs for API updates.');
|
||||
}
|
||||
});
|
||||
if (!ele.children.length) {
|
||||
console.warn('<ion-refresher> should now have an inner <ion-refresher-content> component. Please review the Refresher docs for API updates.');
|
||||
}
|
||||
}
|
||||
|
||||
private _onStart(ev: TouchEvent): any {
|
||||
@ -233,6 +219,13 @@ export class Refresher {
|
||||
let coord = pointerCoord(ev);
|
||||
console.debug('Pull-to-refresh, onStart', ev.type, 'y:', coord.y);
|
||||
|
||||
if (this._content.adjustedTop > 0) {
|
||||
let newTop = this._content.adjustedTop + 'px';
|
||||
if (this._top !== newTop) {
|
||||
this._top = newTop;
|
||||
}
|
||||
}
|
||||
|
||||
this.startY = this.currentY = coord.y;
|
||||
this.progress = 0;
|
||||
this.state = STATE_PULLING;
|
||||
|
@ -1,12 +1,12 @@
|
||||
import {Component} from '@angular/core';
|
||||
import {ionicBootstrap} from '../../../../../src';
|
||||
import {ionicBootstrap, Refresher} from '../../../../../src';
|
||||
|
||||
|
||||
@Component({
|
||||
templateUrl: 'main.html'
|
||||
})
|
||||
class E2EApp {
|
||||
items = [];
|
||||
class Page1 {
|
||||
items: string[] = [];
|
||||
|
||||
constructor() {
|
||||
for (var i = 0; i < 15; i++) {
|
||||
@ -14,10 +14,10 @@ class E2EApp {
|
||||
}
|
||||
}
|
||||
|
||||
doRefresh(refresher) {
|
||||
doRefresh(refresher: Refresher) {
|
||||
console.info('Begin async operation');
|
||||
|
||||
getAsyncData().then(newData => {
|
||||
getAsyncData().then((newData: string[]) => {
|
||||
for (var i = 0; i < newData.length; i++) {
|
||||
this.items.unshift( newData[i] );
|
||||
}
|
||||
@ -27,11 +27,11 @@ class E2EApp {
|
||||
});
|
||||
}
|
||||
|
||||
doStart(refresher) {
|
||||
doStart(refresher: Refresher) {
|
||||
console.info('Refresher, start');
|
||||
}
|
||||
|
||||
doPulling(refresher) {
|
||||
doPulling(refresher: Refresher) {
|
||||
console.info('Pulling', refresher.progress);
|
||||
}
|
||||
|
||||
@ -42,7 +42,7 @@ function getAsyncData() {
|
||||
return new Promise(resolve => {
|
||||
|
||||
setTimeout(() => {
|
||||
let data = [];
|
||||
let data: string[] = [];
|
||||
for (var i = 0; i < 3; i++) {
|
||||
data.push( getRandomData() );
|
||||
}
|
||||
@ -85,4 +85,12 @@ const data = [
|
||||
'Drive Angry'
|
||||
];
|
||||
|
||||
|
||||
@Component({
|
||||
template: '<ion-nav [root]="rootPage"></ion-nav>'
|
||||
})
|
||||
class E2EApp {
|
||||
rootPage = Page1;
|
||||
}
|
||||
|
||||
ionicBootstrap(E2EApp);
|
||||
|
Reference in New Issue
Block a user