fix(refresher): adjust location after layout updates

This commit is contained in:
Adam Bradley
2016-06-21 12:46:49 -05:00
parent 22fad4c4a3
commit 603000fa72
4 changed files with 53 additions and 40 deletions

View File

@ -64,8 +64,6 @@ export class Content extends Ion {
private _paddingRight: number; private _paddingRight: number;
private _paddingBottom: number; private _paddingBottom: number;
private _paddingLeft: number; private _paddingLeft: number;
private _lastTop: number;
private _lastBottom: number;
private _scrollPadding: number; private _scrollPadding: number;
private _headerHeight: number; private _headerHeight: number;
private _footerHeight: number; private _footerHeight: number;
@ -78,6 +76,16 @@ export class Content extends Ion {
private _sbPadding: boolean; private _sbPadding: boolean;
private _fullscreen: boolean; private _fullscreen: boolean;
/**
* @private
*/
adjustedTop: number;
/**
* @private
*/
adjustedBottom: number;
constructor( constructor(
private _elementRef: ElementRef, private _elementRef: ElementRef,
private _config: Config, private _config: Config,
@ -510,16 +518,18 @@ export class Content extends Ion {
if (this._tabbarPlacement === 'top') { if (this._tabbarPlacement === 'top') {
newVal += this._tabbarHeight; newVal += this._tabbarHeight;
} }
if (newVal !== this._lastTop) { if (newVal !== this.adjustedTop) {
this._scrollEle.style.paddingTop = (newVal > 0 ? newVal + 'px' : ''); this._scrollEle.style.paddingTop = (newVal > 0 ? newVal + 'px' : '');
this.adjustedTop = newVal;
} }
newVal = this._footerHeight + this._paddingBottom; newVal = this._footerHeight + this._paddingBottom;
if (this._tabbarPlacement === 'bottom') { if (this._tabbarPlacement === 'bottom') {
newVal += this._tabbarHeight; newVal += this._tabbarHeight;
} }
if (newVal !== this._lastBottom) { if (newVal !== this.adjustedBottom) {
this._scrollEle.style.paddingBottom = (newVal > 0 ? newVal + 'px' : ''); this._scrollEle.style.paddingBottom = (newVal > 0 ? newVal + 'px' : '');
this.adjustedBottom = newVal;
} }
} else { } else {
@ -528,16 +538,18 @@ export class Content extends Ion {
if (this._tabbarPlacement === 'top') { if (this._tabbarPlacement === 'top') {
newVal += this._tabbarHeight; newVal += this._tabbarHeight;
} }
if (newVal !== this._lastTop) { if (newVal !== this.adjustedTop) {
this._scrollEle.style.marginTop = (newVal > 0 ? newVal + 'px' : ''); this._scrollEle.style.marginTop = (newVal > 0 ? newVal + 'px' : '');
this.adjustedTop = newVal;
} }
newVal = this._footerHeight; newVal = this._footerHeight;
if (this._tabbarPlacement === 'bottom') { if (this._tabbarPlacement === 'bottom') {
newVal += this._tabbarHeight; newVal += this._tabbarHeight;
} }
if (newVal !== this._lastBottom) { if (newVal !== this.adjustedBottom) {
this._scrollEle.style.marginBottom = (newVal > 0 ? newVal + 'px' : ''); this._scrollEle.style.marginBottom = (newVal > 0 ? newVal + 'px' : '');
this.adjustedBottom = newVal;
} }
} }

View File

@ -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 { Content } from '../content/content';
import {Icon} from '../icon/icon'; import { CSS, pointerCoord } from '../../util/dom';
import {isTrueProperty} from '../../util/util'; import { isTrueProperty } from '../../util/util';
import {CSS, pointerCoord, transitionEnd} from '../../util/dom'; import { PointerEvents, UIEventManager } from '../../util/ui-event-manager';
import {PointerEvents, UIEventManager} from '../../util/ui-event-manager';
/** /**
@ -90,7 +89,8 @@ import {PointerEvents, UIEventManager} from '../../util/ui-event-manager';
@Directive({ @Directive({
selector: 'ion-refresher', selector: 'ion-refresher',
host: { host: {
'[class.refresher-active]': 'state !== "inactive"' '[class.refresher-active]': 'state !== "inactive"',
'[style.top]': '_top'
} }
}) })
export class Refresher { export class Refresher {
@ -100,6 +100,7 @@ export class Refresher {
private _isEnabled: boolean = true; private _isEnabled: boolean = true;
private _events: UIEventManager = new UIEventManager(false); private _events: UIEventManager = new UIEventManager(false);
private _pointerEvents: PointerEvents; private _pointerEvents: PointerEvents;
private _top: string = '';
/** /**
* The current state which the refresher is in. The refresher's states include: * 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(); @Output() ionStart: EventEmitter<Refresher> = new EventEmitter();
constructor( constructor(@Host() private _content: Content, private _zone: NgZone) {
@Host() private _content: Content,
private _zone: NgZone,
elementRef: ElementRef) {
_content.addCssClass('has-refresher'); _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 { private _onStart(ev: TouchEvent): any {
@ -233,6 +219,13 @@ export class Refresher {
let coord = pointerCoord(ev); let coord = pointerCoord(ev);
console.debug('Pull-to-refresh, onStart', ev.type, 'y:', coord.y); 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.startY = this.currentY = coord.y;
this.progress = 0; this.progress = 0;
this.state = STATE_PULLING; this.state = STATE_PULLING;

View File

@ -1,12 +1,12 @@
import {Component} from '@angular/core'; import {Component} from '@angular/core';
import {ionicBootstrap} from '../../../../../src'; import {ionicBootstrap, Refresher} from '../../../../../src';
@Component({ @Component({
templateUrl: 'main.html' templateUrl: 'main.html'
}) })
class E2EApp { class Page1 {
items = []; items: string[] = [];
constructor() { constructor() {
for (var i = 0; i < 15; i++) { for (var i = 0; i < 15; i++) {
@ -14,10 +14,10 @@ class E2EApp {
} }
} }
doRefresh(refresher) { doRefresh(refresher: Refresher) {
console.info('Begin async operation'); console.info('Begin async operation');
getAsyncData().then(newData => { getAsyncData().then((newData: string[]) => {
for (var i = 0; i < newData.length; i++) { for (var i = 0; i < newData.length; i++) {
this.items.unshift( newData[i] ); this.items.unshift( newData[i] );
} }
@ -27,11 +27,11 @@ class E2EApp {
}); });
} }
doStart(refresher) { doStart(refresher: Refresher) {
console.info('Refresher, start'); console.info('Refresher, start');
} }
doPulling(refresher) { doPulling(refresher: Refresher) {
console.info('Pulling', refresher.progress); console.info('Pulling', refresher.progress);
} }
@ -42,7 +42,7 @@ function getAsyncData() {
return new Promise(resolve => { return new Promise(resolve => {
setTimeout(() => { setTimeout(() => {
let data = []; let data: string[] = [];
for (var i = 0; i < 3; i++) { for (var i = 0; i < 3; i++) {
data.push( getRandomData() ); data.push( getRandomData() );
} }
@ -85,4 +85,12 @@ const data = [
'Drive Angry' 'Drive Angry'
]; ];
@Component({
template: '<ion-nav [root]="rootPage"></ion-nav>'
})
class E2EApp {
rootPage = Page1;
}
ionicBootstrap(E2EApp); ionicBootstrap(E2EApp);