mirror of
https://github.com/NativeScript/NativeScript.git
synced 2025-08-16 03:31:45 +08:00
fix-next: ensure proper events on tab change (#5468)
This commit is contained in:
@ -1,4 +1,5 @@
|
||||
import * as TKUnit from "../TKUnit";
|
||||
import * as helper from "../ui/helper";
|
||||
import { Page } from "tns-core-modules/ui/page";
|
||||
import { Frame, NavigationEntry, stack } from "tns-core-modules/ui/frame";
|
||||
import { _resetRootView, getRootView } from "tns-core-modules/application";
|
||||
@ -47,8 +48,7 @@ function createTestTabRootEntry() {
|
||||
export function test_reset_frame_to_frame() {
|
||||
const testFrameRoot1 = createTestFrameRootEntry();
|
||||
|
||||
_resetRootView(testFrameRoot1.entry);
|
||||
TKUnit.waitUntilReady(() => testFrameRoot1.page.isLoaded);
|
||||
helper.waitUntilNavigatedTo(testFrameRoot1.page, () => _resetRootView(testFrameRoot1.entry));
|
||||
|
||||
const rootView1 = getRootView();
|
||||
const frameStack1 = stack();
|
||||
@ -57,8 +57,7 @@ export function test_reset_frame_to_frame() {
|
||||
|
||||
const testFrameRoot2 = createTestFrameRootEntry();
|
||||
|
||||
_resetRootView(testFrameRoot2.entry);
|
||||
TKUnit.waitUntilReady(() => testFrameRoot2.page.isLoaded);
|
||||
helper.waitUntilNavigatedTo(testFrameRoot2.page, () => _resetRootView(testFrameRoot2.entry));
|
||||
|
||||
const rootView2 = getRootView();
|
||||
const frameStack2 = stack();
|
||||
@ -69,8 +68,7 @@ export function test_reset_frame_to_frame() {
|
||||
export function test_reset_frame_to_tab() {
|
||||
const testFrameRoot = createTestFrameRootEntry();
|
||||
|
||||
_resetRootView(testFrameRoot.entry);
|
||||
TKUnit.waitUntilReady(() => testFrameRoot.page.isLoaded);
|
||||
helper.waitUntilNavigatedTo(testFrameRoot.page, () => _resetRootView(testFrameRoot.entry));
|
||||
|
||||
const rootView1 = getRootView();
|
||||
const frameStack1 = stack();
|
||||
@ -79,8 +77,7 @@ export function test_reset_frame_to_tab() {
|
||||
|
||||
const testTabRoot = createTestTabRootEntry();
|
||||
|
||||
_resetRootView(testTabRoot.entry);
|
||||
TKUnit.waitUntilReady(() => testTabRoot.page.isLoaded);
|
||||
helper.waitUntilNavigatedTo(testTabRoot.page, () => _resetRootView(testTabRoot.entry));
|
||||
|
||||
const rootView2 = getRootView();
|
||||
const frameStack2 = stack();
|
||||
@ -91,8 +88,7 @@ export function test_reset_frame_to_tab() {
|
||||
export function test_reset_tab_to_frame() {
|
||||
const testTabRoot = createTestTabRootEntry();
|
||||
|
||||
_resetRootView(testTabRoot.entry);
|
||||
TKUnit.waitUntilReady(() => testTabRoot.page.isLoaded);
|
||||
helper.waitUntilNavigatedTo(testTabRoot.page, () => _resetRootView(testTabRoot.entry));
|
||||
|
||||
const rootView2 = getRootView();
|
||||
const frameStack2 = stack();
|
||||
@ -101,8 +97,7 @@ export function test_reset_tab_to_frame() {
|
||||
|
||||
const testFrameRoot = createTestFrameRootEntry();
|
||||
|
||||
_resetRootView(testFrameRoot.entry);
|
||||
TKUnit.waitUntilReady(() => testFrameRoot.page.isLoaded);
|
||||
helper.waitUntilNavigatedTo(testFrameRoot.page, () => _resetRootView(testFrameRoot.entry));
|
||||
|
||||
const rootView1 = getRootView();
|
||||
const frameStack1 = stack();
|
||||
@ -113,8 +108,7 @@ export function test_reset_tab_to_frame() {
|
||||
export function test_reset_tab_to_tab() {
|
||||
const testTabRoot1 = createTestTabRootEntry();
|
||||
|
||||
_resetRootView(testTabRoot1.entry);
|
||||
TKUnit.waitUntilReady(() => testTabRoot1.page.isLoaded);
|
||||
helper.waitUntilNavigatedTo(testTabRoot1.page, () => _resetRootView(testTabRoot1.entry));
|
||||
|
||||
const rootView1 = getRootView();
|
||||
const frameStack1 = stack();
|
||||
@ -123,8 +117,7 @@ export function test_reset_tab_to_tab() {
|
||||
|
||||
const testTabRoot2 = createTestTabRootEntry();
|
||||
|
||||
_resetRootView(testTabRoot2.entry);
|
||||
TKUnit.waitUntilReady(() => testTabRoot2.page.isLoaded);
|
||||
helper.waitUntilNavigatedTo(testTabRoot2.page, () => _resetRootView(testTabRoot2.entry));
|
||||
|
||||
const rootView2 = getRootView();
|
||||
const frameStack2 = stack();
|
||||
@ -132,6 +125,20 @@ export function test_reset_tab_to_tab() {
|
||||
TKUnit.assertEqual(frameStack2.length, 2);
|
||||
};
|
||||
|
||||
export function test_reset_during_tab_index_change() {
|
||||
const testTabRoot = createTestTabRootEntry();
|
||||
|
||||
helper.waitUntilNavigatedTo(testTabRoot.page, () => _resetRootView(testTabRoot.entry));
|
||||
|
||||
testTabRoot.root.selectedIndex = 1;
|
||||
|
||||
const testFrameRoot = createTestFrameRootEntry();
|
||||
|
||||
helper.waitUntilNavigatedTo(testFrameRoot.page, () => _resetRootView(testFrameRoot.entry));
|
||||
|
||||
TKUnit.assertTrue(true);
|
||||
}
|
||||
|
||||
export function tearDownModule() {
|
||||
// reset the root to frame for other tests
|
||||
const resetFrameRoot = createTestFrameRootEntry();
|
||||
|
@ -165,6 +165,9 @@ allTests["TAB-VIEW"] = tabViewTests;
|
||||
import * as tabViewNavigationTests from "./ui/tab-view/tab-view-navigation-tests";
|
||||
allTests["TAB-VIEW-NAVIGATION"] = tabViewNavigationTests;
|
||||
|
||||
import * as tabViewRootTests from "./ui/tab-view/tab-view-root-tests";
|
||||
allTests["TAB-VIEW-ROOT"] = tabViewRootTests;
|
||||
|
||||
import * as imageTests from "./ui/image/image-tests";
|
||||
allTests["IMAGE"] = imageTests;
|
||||
|
||||
|
@ -154,6 +154,18 @@ export function getClearCurrentPage(): Page {
|
||||
return page;
|
||||
}
|
||||
|
||||
export function waitUntilNavigatedTo(page: Page, action: Function) {
|
||||
let completed = false;
|
||||
function navigatedTo(args) {
|
||||
args.object.page.off("navigatedTo", navigatedTo);
|
||||
completed = true;
|
||||
}
|
||||
|
||||
page.on("navigatedTo", navigatedTo);
|
||||
action();
|
||||
TKUnit.waitUntilReady(() => completed, 100);
|
||||
}
|
||||
|
||||
export function waitUntilNavigatedFrom(action: Function) {
|
||||
const currentPage = frame.topmost().currentPage;
|
||||
let completed = false;
|
||||
|
91
tests/app/ui/tab-view/tab-view-root-tests.ts
Normal file
91
tests/app/ui/tab-view/tab-view-root-tests.ts
Normal file
@ -0,0 +1,91 @@
|
||||
import * as helper from "../helper";
|
||||
import TKUnit = require("../../TKUnit");
|
||||
import { _resetRootView } from "tns-core-modules/application/";
|
||||
import { Frame, NavigationEntry } from "tns-core-modules/ui/frame";
|
||||
import { Page } from "tns-core-modules/ui/page";
|
||||
import { TabView, TabViewItem } from "tns-core-modules/ui/tab-view";
|
||||
|
||||
export function test_whenChangingTabsWithFramesCorrectEventsAreRaised() {
|
||||
const actualEventsRaised = [];
|
||||
|
||||
function attachPageEventHandlers(page: Page) {
|
||||
page.on(Page.loadedEvent, () => actualEventsRaised.push(`${page.id} loaded`));
|
||||
page.on(Page.unloadedEvent, () => actualEventsRaised.push(`${page.id} unloaded`));
|
||||
page.on(Page.navigatingToEvent, () => actualEventsRaised.push(`${page.id} navigatingTo`));
|
||||
page.on(Page.navigatingFromEvent, () => actualEventsRaised.push(`${page.id} navigatingFrom`));
|
||||
page.on(Page.navigatedToEvent, () => actualEventsRaised.push(`${page.id} navigatedTo`));
|
||||
page.on(Page.navigatedFromEvent, () => actualEventsRaised.push(`${page.id} navigatedFrom`));
|
||||
}
|
||||
|
||||
function attachFrameEventHandlers(frame: Frame) {
|
||||
frame.on(Frame.loadedEvent, () => actualEventsRaised.push(`${frame.id} loaded`));
|
||||
frame.on(Frame.unloadedEvent, () => actualEventsRaised.push(`${frame.id} unloaded`));
|
||||
}
|
||||
|
||||
const page1 = new Page();
|
||||
page1.id = "Tab1 Frame1 Page1";
|
||||
attachPageEventHandlers(page1);
|
||||
|
||||
const frame1 = new Frame();
|
||||
frame1.navigate(() => page1);
|
||||
frame1.id = "Tab1 Frame1";
|
||||
attachFrameEventHandlers(frame1);
|
||||
|
||||
const page2 = new Page();
|
||||
page2.id = "Tab2 Frame2 Page2";
|
||||
attachPageEventHandlers(page2);
|
||||
|
||||
const frame2 = new Frame();
|
||||
frame2.navigate(() => page2);
|
||||
frame2.id = "Tab2 Frame2";
|
||||
attachFrameEventHandlers(frame2);
|
||||
|
||||
const tabView = new TabView();
|
||||
const tabEntry1 = new TabViewItem();
|
||||
tabEntry1.title = "frame1";
|
||||
tabEntry1.view = frame1;
|
||||
const tabEntry2 = new TabViewItem();
|
||||
tabEntry2.title = "frame2";
|
||||
tabEntry2.view = frame2;
|
||||
tabView.items = [tabEntry1, tabEntry2];
|
||||
|
||||
const entry: NavigationEntry = {
|
||||
create: () => tabView
|
||||
};
|
||||
|
||||
helper.waitUntilNavigatedTo(page1, () => _resetRootView(entry));
|
||||
helper.waitUntilNavigatedTo(page2, () => tabView.selectedIndex = 1);
|
||||
tabView.selectedIndex = 0;
|
||||
TKUnit.waitUntilReady(() => page1.isLoaded);
|
||||
|
||||
const expectedEventsRaised = [
|
||||
"Tab1 Frame1 loaded",
|
||||
"Tab1 Frame1 Page1 navigatingTo",
|
||||
"Tab1 Frame1 Page1 loaded",
|
||||
"Tab1 Frame1 Page1 navigatedTo",
|
||||
"Tab1 Frame1 Page1 unloaded",
|
||||
"Tab1 Frame1 unloaded",
|
||||
"Tab2 Frame2 loaded",
|
||||
"Tab2 Frame2 Page2 navigatingTo",
|
||||
"Tab2 Frame2 Page2 loaded",
|
||||
"Tab2 Frame2 Page2 navigatedTo",
|
||||
"Tab2 Frame2 Page2 unloaded",
|
||||
"Tab2 Frame2 unloaded",
|
||||
"Tab1 Frame1 Page1 loaded",
|
||||
"Tab1 Frame1 loaded"
|
||||
];
|
||||
|
||||
TKUnit.arrayAssert(actualEventsRaised, expectedEventsRaised);
|
||||
}
|
||||
|
||||
export function tearDownModule() {
|
||||
const page = new Page();
|
||||
const frame = new Frame();
|
||||
frame.navigate(() => page);
|
||||
|
||||
const entry: NavigationEntry = {
|
||||
create: () => frame
|
||||
};
|
||||
|
||||
helper.waitUntilNavigatedTo(page, () => _resetRootView(entry));
|
||||
}
|
@ -201,9 +201,7 @@ export class Frame extends FrameBase {
|
||||
const currentEntryChanged = current !== entry;
|
||||
if (currentEntryChanged) {
|
||||
this._updateBackstack(entry, isBack);
|
||||
}
|
||||
|
||||
if (currentEntryChanged) {
|
||||
// If activity was destroyed we need to destroy fragment and UI
|
||||
// of current and new entries.
|
||||
if (this._tearDownPending) {
|
||||
@ -936,7 +934,9 @@ class ActivityCallbacksImplementation implements AndroidActivityCallbacks {
|
||||
|
||||
public resetActivityContent(activity: android.app.Activity): void {
|
||||
if (this._rootView) {
|
||||
// if we already have a root view, we reset it.
|
||||
const manager = this._rootView._getFragmentManager();
|
||||
manager.executePendingTransactions();
|
||||
|
||||
this._rootView._onRootViewReset();
|
||||
}
|
||||
// Delete previously cached root view in order to recreate it.
|
||||
|
@ -38,11 +38,13 @@ export class Frame extends FrameBase {
|
||||
}
|
||||
|
||||
public setCurrent(entry: BackstackEntry, isBack: boolean): void {
|
||||
if (entry !== this._currentEntry) {
|
||||
const current = this._currentEntry;
|
||||
const currentEntryChanged = current !== entry;
|
||||
if (currentEntryChanged) {
|
||||
this._updateBackstack(entry, isBack);
|
||||
}
|
||||
|
||||
super.setCurrent(entry, isBack);
|
||||
super.setCurrent(entry, isBack);
|
||||
}
|
||||
}
|
||||
|
||||
@profile
|
||||
|
@ -32,7 +32,7 @@ class UITabBarControllerImpl extends UITabBarController {
|
||||
public viewWillAppear(animated: boolean): void {
|
||||
super.viewWillAppear(animated);
|
||||
const owner = this._owner.get();
|
||||
if(!owner){
|
||||
if (!owner) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -147,7 +147,7 @@ function updateItemIconPosition(tabBarItem: UITabBarItem): void {
|
||||
|
||||
export class TabViewItem extends TabViewItemBase {
|
||||
private __controller: UIViewController;
|
||||
|
||||
|
||||
public setViewController(controller: UIViewController, nativeView: UIView) {
|
||||
this.__controller = controller;
|
||||
this.setNativeView(nativeView);
|
||||
@ -295,7 +295,7 @@ export class TabView extends TabViewBase {
|
||||
|
||||
private getViewController(item: TabViewItem): UIViewController {
|
||||
let newController: UIViewController = item.view ? item.view.viewController : null;
|
||||
|
||||
|
||||
if (newController) {
|
||||
item.setViewController(newController, newController.view);
|
||||
return newController;
|
||||
@ -399,6 +399,7 @@ export class TabView extends TabViewBase {
|
||||
}
|
||||
|
||||
if (value > -1) {
|
||||
(<any>this._ios)._willSelectViewController = this._ios.viewControllers[value];
|
||||
this._ios.selectedIndex = value;
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user