mirror of
https://github.com/NativeScript/NativeScript.git
synced 2025-08-17 21:01:34 +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 TKUnit from "../TKUnit";
|
||||||
|
import * as helper from "../ui/helper";
|
||||||
import { Page } from "tns-core-modules/ui/page";
|
import { Page } from "tns-core-modules/ui/page";
|
||||||
import { Frame, NavigationEntry, stack } from "tns-core-modules/ui/frame";
|
import { Frame, NavigationEntry, stack } from "tns-core-modules/ui/frame";
|
||||||
import { _resetRootView, getRootView } from "tns-core-modules/application";
|
import { _resetRootView, getRootView } from "tns-core-modules/application";
|
||||||
@ -47,8 +48,7 @@ function createTestTabRootEntry() {
|
|||||||
export function test_reset_frame_to_frame() {
|
export function test_reset_frame_to_frame() {
|
||||||
const testFrameRoot1 = createTestFrameRootEntry();
|
const testFrameRoot1 = createTestFrameRootEntry();
|
||||||
|
|
||||||
_resetRootView(testFrameRoot1.entry);
|
helper.waitUntilNavigatedTo(testFrameRoot1.page, () => _resetRootView(testFrameRoot1.entry));
|
||||||
TKUnit.waitUntilReady(() => testFrameRoot1.page.isLoaded);
|
|
||||||
|
|
||||||
const rootView1 = getRootView();
|
const rootView1 = getRootView();
|
||||||
const frameStack1 = stack();
|
const frameStack1 = stack();
|
||||||
@ -57,8 +57,7 @@ export function test_reset_frame_to_frame() {
|
|||||||
|
|
||||||
const testFrameRoot2 = createTestFrameRootEntry();
|
const testFrameRoot2 = createTestFrameRootEntry();
|
||||||
|
|
||||||
_resetRootView(testFrameRoot2.entry);
|
helper.waitUntilNavigatedTo(testFrameRoot2.page, () => _resetRootView(testFrameRoot2.entry));
|
||||||
TKUnit.waitUntilReady(() => testFrameRoot2.page.isLoaded);
|
|
||||||
|
|
||||||
const rootView2 = getRootView();
|
const rootView2 = getRootView();
|
||||||
const frameStack2 = stack();
|
const frameStack2 = stack();
|
||||||
@ -69,8 +68,7 @@ export function test_reset_frame_to_frame() {
|
|||||||
export function test_reset_frame_to_tab() {
|
export function test_reset_frame_to_tab() {
|
||||||
const testFrameRoot = createTestFrameRootEntry();
|
const testFrameRoot = createTestFrameRootEntry();
|
||||||
|
|
||||||
_resetRootView(testFrameRoot.entry);
|
helper.waitUntilNavigatedTo(testFrameRoot.page, () => _resetRootView(testFrameRoot.entry));
|
||||||
TKUnit.waitUntilReady(() => testFrameRoot.page.isLoaded);
|
|
||||||
|
|
||||||
const rootView1 = getRootView();
|
const rootView1 = getRootView();
|
||||||
const frameStack1 = stack();
|
const frameStack1 = stack();
|
||||||
@ -79,8 +77,7 @@ export function test_reset_frame_to_tab() {
|
|||||||
|
|
||||||
const testTabRoot = createTestTabRootEntry();
|
const testTabRoot = createTestTabRootEntry();
|
||||||
|
|
||||||
_resetRootView(testTabRoot.entry);
|
helper.waitUntilNavigatedTo(testTabRoot.page, () => _resetRootView(testTabRoot.entry));
|
||||||
TKUnit.waitUntilReady(() => testTabRoot.page.isLoaded);
|
|
||||||
|
|
||||||
const rootView2 = getRootView();
|
const rootView2 = getRootView();
|
||||||
const frameStack2 = stack();
|
const frameStack2 = stack();
|
||||||
@ -91,8 +88,7 @@ export function test_reset_frame_to_tab() {
|
|||||||
export function test_reset_tab_to_frame() {
|
export function test_reset_tab_to_frame() {
|
||||||
const testTabRoot = createTestTabRootEntry();
|
const testTabRoot = createTestTabRootEntry();
|
||||||
|
|
||||||
_resetRootView(testTabRoot.entry);
|
helper.waitUntilNavigatedTo(testTabRoot.page, () => _resetRootView(testTabRoot.entry));
|
||||||
TKUnit.waitUntilReady(() => testTabRoot.page.isLoaded);
|
|
||||||
|
|
||||||
const rootView2 = getRootView();
|
const rootView2 = getRootView();
|
||||||
const frameStack2 = stack();
|
const frameStack2 = stack();
|
||||||
@ -101,8 +97,7 @@ export function test_reset_tab_to_frame() {
|
|||||||
|
|
||||||
const testFrameRoot = createTestFrameRootEntry();
|
const testFrameRoot = createTestFrameRootEntry();
|
||||||
|
|
||||||
_resetRootView(testFrameRoot.entry);
|
helper.waitUntilNavigatedTo(testFrameRoot.page, () => _resetRootView(testFrameRoot.entry));
|
||||||
TKUnit.waitUntilReady(() => testFrameRoot.page.isLoaded);
|
|
||||||
|
|
||||||
const rootView1 = getRootView();
|
const rootView1 = getRootView();
|
||||||
const frameStack1 = stack();
|
const frameStack1 = stack();
|
||||||
@ -113,8 +108,7 @@ export function test_reset_tab_to_frame() {
|
|||||||
export function test_reset_tab_to_tab() {
|
export function test_reset_tab_to_tab() {
|
||||||
const testTabRoot1 = createTestTabRootEntry();
|
const testTabRoot1 = createTestTabRootEntry();
|
||||||
|
|
||||||
_resetRootView(testTabRoot1.entry);
|
helper.waitUntilNavigatedTo(testTabRoot1.page, () => _resetRootView(testTabRoot1.entry));
|
||||||
TKUnit.waitUntilReady(() => testTabRoot1.page.isLoaded);
|
|
||||||
|
|
||||||
const rootView1 = getRootView();
|
const rootView1 = getRootView();
|
||||||
const frameStack1 = stack();
|
const frameStack1 = stack();
|
||||||
@ -123,8 +117,7 @@ export function test_reset_tab_to_tab() {
|
|||||||
|
|
||||||
const testTabRoot2 = createTestTabRootEntry();
|
const testTabRoot2 = createTestTabRootEntry();
|
||||||
|
|
||||||
_resetRootView(testTabRoot2.entry);
|
helper.waitUntilNavigatedTo(testTabRoot2.page, () => _resetRootView(testTabRoot2.entry));
|
||||||
TKUnit.waitUntilReady(() => testTabRoot2.page.isLoaded);
|
|
||||||
|
|
||||||
const rootView2 = getRootView();
|
const rootView2 = getRootView();
|
||||||
const frameStack2 = stack();
|
const frameStack2 = stack();
|
||||||
@ -132,6 +125,20 @@ export function test_reset_tab_to_tab() {
|
|||||||
TKUnit.assertEqual(frameStack2.length, 2);
|
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() {
|
export function tearDownModule() {
|
||||||
// reset the root to frame for other tests
|
// reset the root to frame for other tests
|
||||||
const resetFrameRoot = createTestFrameRootEntry();
|
const resetFrameRoot = createTestFrameRootEntry();
|
||||||
|
@ -165,6 +165,9 @@ allTests["TAB-VIEW"] = tabViewTests;
|
|||||||
import * as tabViewNavigationTests from "./ui/tab-view/tab-view-navigation-tests";
|
import * as tabViewNavigationTests from "./ui/tab-view/tab-view-navigation-tests";
|
||||||
allTests["TAB-VIEW-NAVIGATION"] = tabViewNavigationTests;
|
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";
|
import * as imageTests from "./ui/image/image-tests";
|
||||||
allTests["IMAGE"] = imageTests;
|
allTests["IMAGE"] = imageTests;
|
||||||
|
|
||||||
|
@ -154,6 +154,18 @@ export function getClearCurrentPage(): Page {
|
|||||||
return 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) {
|
export function waitUntilNavigatedFrom(action: Function) {
|
||||||
const currentPage = frame.topmost().currentPage;
|
const currentPage = frame.topmost().currentPage;
|
||||||
let completed = false;
|
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;
|
const currentEntryChanged = current !== entry;
|
||||||
if (currentEntryChanged) {
|
if (currentEntryChanged) {
|
||||||
this._updateBackstack(entry, isBack);
|
this._updateBackstack(entry, isBack);
|
||||||
}
|
|
||||||
|
|
||||||
if (currentEntryChanged) {
|
|
||||||
// If activity was destroyed we need to destroy fragment and UI
|
// If activity was destroyed we need to destroy fragment and UI
|
||||||
// of current and new entries.
|
// of current and new entries.
|
||||||
if (this._tearDownPending) {
|
if (this._tearDownPending) {
|
||||||
@ -936,7 +934,9 @@ class ActivityCallbacksImplementation implements AndroidActivityCallbacks {
|
|||||||
|
|
||||||
public resetActivityContent(activity: android.app.Activity): void {
|
public resetActivityContent(activity: android.app.Activity): void {
|
||||||
if (this._rootView) {
|
if (this._rootView) {
|
||||||
// if we already have a root view, we reset it.
|
const manager = this._rootView._getFragmentManager();
|
||||||
|
manager.executePendingTransactions();
|
||||||
|
|
||||||
this._rootView._onRootViewReset();
|
this._rootView._onRootViewReset();
|
||||||
}
|
}
|
||||||
// Delete previously cached root view in order to recreate it.
|
// Delete previously cached root view in order to recreate it.
|
||||||
|
@ -38,12 +38,14 @@ export class Frame extends FrameBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public setCurrent(entry: BackstackEntry, isBack: boolean): void {
|
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);
|
this._updateBackstack(entry, isBack);
|
||||||
}
|
|
||||||
|
|
||||||
super.setCurrent(entry, isBack);
|
super.setCurrent(entry, isBack);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@profile
|
@profile
|
||||||
public _navigateCore(backstackEntry: BackstackEntry) {
|
public _navigateCore(backstackEntry: BackstackEntry) {
|
||||||
|
@ -399,6 +399,7 @@ export class TabView extends TabViewBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (value > -1) {
|
if (value > -1) {
|
||||||
|
(<any>this._ios)._willSelectViewController = this._ios.viewControllers[value];
|
||||||
this._ios.selectedIndex = value;
|
this._ios.selectedIndex = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user