Merge pull request #975 from NativeScript/nnikolov/Issue926

Fixed issue #926.
This commit is contained in:
Nedyalko Nikolov
2015-10-23 10:25:54 +03:00
6 changed files with 100 additions and 37 deletions

View File

@ -394,6 +394,46 @@ export function test_WhenPageIsLoadedFrameCurrentPageIsTheSameInstance() {
} }
} }
export function test_WhenNavigatingForwardAndBack_IsBackNavigationIsCorrect() {
var page1;
var page2;
var forwardCounter = 0;
var backCounter = 0;
var loadedEventHandler = function (args: PageModule.NavigatedData) {
if (args.isBackNavigation) {
backCounter++;
}
else {
forwardCounter++;
}
}
var pageFactory1 = function (): PageModule.Page {
page1 = new PageModule.Page();
page1.on(PageModule.Page.navigatedToEvent, loadedEventHandler);
return page1;
};
var pageFactory2 = function (): PageModule.Page {
page2 = new PageModule.Page();
page2.on(PageModule.Page.navigatedToEvent, loadedEventHandler);
return page2;
};
try {
helper.navigate(pageFactory1);
helper.navigate(pageFactory2);
helper.goBack();
TKUnit.assertEqual(forwardCounter, 2, "Forward navigation counter should be 1");
TKUnit.assertEqual(backCounter, 1, "Backward navigation counter should be 1");
page1.off(PageModule.Page.navigatedToEvent, loadedEventHandler);
page2.off(PageModule.Page.navigatedToEvent, loadedEventHandler);
}
finally {
helper.goBack();
}
}
//export function test_ModalPage_Layout_is_Correct() { //export function test_ModalPage_Layout_is_Correct() {
// var testPage: PageModule.Page; // var testPage: PageModule.Page;
// var label: LabelModule.Label; // var label: LabelModule.Label;

View File

@ -222,7 +222,7 @@ export class Frame extends view.CustomLayoutView implements definition.Frame {
private performNavigation(navigationContext: NavigationContext) { private performNavigation(navigationContext: NavigationContext) {
var navContext = navigationContext.entry; var navContext = navigationContext.entry;
this._onNavigatingTo(navContext); this._onNavigatingTo(navContext, navigationContext.isBackNavigation);
if (navigationContext.entry.entry.clearHistory) { if (navigationContext.entry.entry.clearHistory) {
this._backStack.length = 0; this._backStack.length = 0;
@ -237,7 +237,7 @@ export class Frame extends view.CustomLayoutView implements definition.Frame {
private performGoBack(navigationContext: NavigationContext) { private performGoBack(navigationContext: NavigationContext) {
var navContext = navigationContext.entry; var navContext = navigationContext.entry;
this._onNavigatingTo(navContext); this._onNavigatingTo(navContext, navigationContext.isBackNavigation);
this._goBackCore(navContext); this._goBackCore(navContext);
this._onNavigatedTo(navContext, true); this._onNavigatedTo(navContext, true);
} }
@ -250,12 +250,12 @@ export class Frame extends view.CustomLayoutView implements definition.Frame {
// //
} }
public _onNavigatingTo(backstackEntry: definition.BackstackEntry) { public _onNavigatingTo(backstackEntry: definition.BackstackEntry, isBack: boolean) {
if (this.currentPage) { if (this.currentPage) {
this.currentPage.onNavigatingFrom(); this.currentPage.onNavigatingFrom(isBack);
} }
backstackEntry.resolvedPage.onNavigatingTo(backstackEntry.entry.context); backstackEntry.resolvedPage.onNavigatingTo(backstackEntry.entry.context, isBack);
} }
public _onNavigatedTo(backstackEntry: definition.BackstackEntry, isBack: boolean) { public _onNavigatedTo(backstackEntry: definition.BackstackEntry, isBack: boolean) {

View File

@ -159,11 +159,22 @@ function onFragmentShown(fragment: PageFragmentBody) {
var entry: definition.BackstackEntry = fragment.entry; var entry: definition.BackstackEntry = fragment.entry;
var page: pages.Page = entry.resolvedPage; var page: pages.Page = entry.resolvedPage;
let currentNavigationContext;
let navigationQueue = (<any>frame)._navigationQueue;
for (let i = 0; i < navigationQueue.length; i++) {
if (navigationQueue[i].entry === entry) {
currentNavigationContext = navigationQueue[i];
break;
}
}
var isBack = currentNavigationContext ? currentNavigationContext.isBackNavigation : false;
frame._currentEntry = entry; frame._currentEntry = entry;
// notify the page // notify the page
frame._addView(page); frame._addView(page);
page.onNavigatedTo(); page.onNavigatedTo(isBack);
frame._processNavigationQueue(page); frame._processNavigationQueue(page);
} }
@ -351,7 +362,7 @@ export class Frame extends frameCommon.Frame {
var backstackEntry = this.currentEntry || this._delayedNavigationEntry; var backstackEntry = this.currentEntry || this._delayedNavigationEntry;
if (isRestart) { if (isRestart) {
this._onNavigatingTo(backstackEntry); this._onNavigatingTo(backstackEntry, false);
this._onNavigatedTo(backstackEntry, false); this._onNavigatedTo(backstackEntry, false);
} }
else { else {

View File

@ -304,6 +304,18 @@ class UINavigationControllerImpl extends UINavigationController implements UINav
// This code check if navigation happened through UI (e.g. back button or swipe gesture). // This code check if navigation happened through UI (e.g. back button or swipe gesture).
// When calling goBack on frame isBack will be false. // When calling goBack on frame isBack will be false.
let isBack: boolean = currentEntry && newEntry === currentEntry; let isBack: boolean = currentEntry && newEntry === currentEntry;
let currentNavigationContext;
let navigationQueue = (<any>frame)._navigationQueue;
for (let i = 0; i < navigationQueue.length; i++) {
if (navigationQueue[i].entry === newEntry) {
currentNavigationContext = navigationQueue[i];
break;
}
}
var isBackNavigation = currentNavigationContext ? currentNavigationContext.isBackNavigation : false;
if (isBack) { if (isBack) {
try { try {
frame._shouldSkipNativePop = true; frame._shouldSkipNativePop = true;
@ -334,7 +346,7 @@ class UINavigationControllerImpl extends UINavigationController implements UINav
frame._updateActionBar(newPage); frame._updateActionBar(newPage);
// notify the page // notify the page
newPage.onNavigatedTo(); newPage.onNavigatedTo(isBack || isBackNavigation);
frame._processNavigationQueue(newPage); frame._processNavigationQueue(newPage);
} }

View File

@ -8,11 +8,11 @@ import fs = require("file-system");
import frameCommon = require("../frame/frame-common"); import frameCommon = require("../frame/frame-common");
import {ActionBar} from "ui/action-bar"; import {ActionBar} from "ui/action-bar";
import {DependencyObservable, PropertyMetadata, PropertyMetadataSettings, PropertyChangeData, Property, ValueSource} from "ui/core/dependency-observable"; import {DependencyObservable, PropertyMetadata, PropertyMetadataSettings, PropertyChangeData, Property, ValueSource} from "ui/core/dependency-observable";
import platform = require("platform");
import proxy = require("ui/core/proxy"); import proxy = require("ui/core/proxy");
// on Android we explicitly set propertySettings to None because android will invalidate its layout (skip unnecessary native call). // on Android we explicitly set propertySettings to None because android will invalidate its layout (skip unnecessary native call).
var AffectsLayout = platform.device.os === platform.platformNames.android ? PropertyMetadataSettings.None : PropertyMetadataSettings.AffectsLayout; var AffectsLayout = global.android ? PropertyMetadataSettings.None : PropertyMetadataSettings.AffectsLayout;
var backgroundSpanUnderStatusBarProperty = new Property("backgroundSpanUnderStatusBar", "Page", new proxy.PropertyMetadata(false, AffectsLayout)); var backgroundSpanUnderStatusBarProperty = new Property("backgroundSpanUnderStatusBar", "Page", new proxy.PropertyMetadata(false, AffectsLayout));
@ -163,38 +163,30 @@ export class Page extends ContentView implements dts.Page {
return <frame.Frame>this.parent; return <frame.Frame>this.parent;
} }
public onNavigatingTo(context: any) { private createNavigatedData(eventName: string, isBackNavigation: boolean): dts.NavigatedData {
return {
eventName: eventName,
object: this,
context: this.navigationContext,
isBackNavigation: isBackNavigation
};
}
public onNavigatingTo(context: any, isBackNavigation: boolean) {
this._navigationContext = context; this._navigationContext = context;
this.notify(this.createNavigatedData(Page.navigatingToEvent, isBackNavigation));
this.notify({
eventName: Page.navigatingToEvent,
object: this,
context: this.navigationContext
});
} }
public onNavigatedTo() { public onNavigatedTo(isBackNavigation: boolean) {
this.notify({ this.notify(this.createNavigatedData(Page.navigatedToEvent, isBackNavigation));
eventName: Page.navigatedToEvent,
object: this,
context: this.navigationContext
});
} }
public onNavigatingFrom() { public onNavigatingFrom(isBackNavigation: boolean) {
this.notify({ this.notify(this.createNavigatedData(Page.navigatingFromEvent, isBackNavigation));
eventName: Page.navigatingFromEvent,
object: this,
context: this.navigationContext
});
} }
public onNavigatedFrom(isBackNavigation: boolean) { public onNavigatedFrom(isBackNavigation: boolean) {
this.notify({ this.notify(this.createNavigatedData(Page.navigatedFromEvent, isBackNavigation));
eventName: Page.navigatedFromEvent,
object: this,
context: this.navigationContext
});
this._navigationContext = undefined; this._navigationContext = undefined;
} }

14
ui/page/page.d.ts vendored
View File

@ -21,6 +21,11 @@ declare module "ui/page" {
* The navigation context (optional, may be undefined) passed to the page navigation events method. * The navigation context (optional, may be undefined) passed to the page navigation events method.
*/ */
context: any; context: any;
/**
* Represents if a navigation is forward or backward.
*/
isBackNavigation: boolean;
} }
/** /**
@ -187,18 +192,21 @@ declare module "ui/page" {
/** /**
* A method called before navigating to the page. * A method called before navigating to the page.
* @param context - The data passed to the page through the NavigationEntry.context property. * @param context - The data passed to the page through the NavigationEntry.context property.
* @param isBackNavigation - True if the Page is being navigated from using the Frame.goBack() method, false otherwise.
*/ */
onNavigatingTo(context: any): void; onNavigatingTo(context: any, isBackNavigation: boolean): void;
/** /**
* A method called after navigated to the page. * A method called after navigated to the page.
* @param isBackNavigation - True if the Page is being navigated from using the Frame.goBack() method, false otherwise.
*/ */
onNavigatedTo(): void; onNavigatedTo(isBackNavigation: boolean): void;
/** /**
* A method called before navigating from the page. * A method called before navigating from the page.
* @param isBackNavigation - True if the Page is being navigated from using the Frame.goBack() method, false otherwise.
*/ */
onNavigatingFrom(): void; onNavigatingFrom(isBackNavigation: boolean): void;
/** /**
* A method called after navigated from the page. * A method called after navigated from the page.