Skip to content

Commit 933073e

Browse files
committed
fix: add '/' path to initial navigation entry + samples
1 parent 8f0d4c2 commit 933073e

File tree

2 files changed

+143
-19
lines changed

2 files changed

+143
-19
lines changed

platform/nativescript/runtime/components/frame.js

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -89,9 +89,14 @@ export default {
8989

9090
notifyPageMounted(pageVm) {
9191
this.$nextTick(_ =>
92-
this.navigate({
93-
create: () => pageVm.$el.nativeView
94-
})
92+
this.navigate(
93+
Object.assign(
94+
{
95+
create: () => pageVm.$el.nativeView
96+
},
97+
this.nativeView.currentEntry ? {} : { path: '/' }
98+
)
99+
)
95100
)
96101
},
97102

samples/app/app-with-ns-router.js

Lines changed: 135 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
const Vue = require('./nativescript-vue')
22

3+
const SCENARIO = 'login'
4+
35
Vue.config.silent = false
46
Vue.config.debug = true
57

@@ -14,7 +16,7 @@ const FrameRouter = function install(Vue, options) {
1416
data: {
1517
routes: options.routes,
1618
path: '/', // current path
17-
stack: [],
19+
stack: ['/'],
1820
data: null,
1921

2022
pending: false
@@ -31,10 +33,15 @@ const FrameRouter = function install(Vue, options) {
3133
this.data = this.pending.data
3234

3335
this.pending = false
36+
navigatorLog(
37+
` *** NAVIGATOR::_confirmPathChange::canGoBack = ${this.frameVM.nativeView.canGoBack()} ***`
38+
)
3439
},
35-
_setPending(path, clear = false, data) {
40+
_setPending(path, clear = false, data, replaceStack) {
3641
navigatorLog(
37-
` *** NAVIGATOR::_setPending(path = ${path}, clear = ${clear}, data = ${data}) ***`
42+
` *** NAVIGATOR::_setPending(path = ${path}, clear = ${clear}, data = ${data}, replaceStack = ${
43+
replaceStack ? replaceStack.join() : undefined
44+
}) ***`
3845
)
3946

4047
let stack = this.stack.slice()
@@ -46,7 +53,7 @@ const FrameRouter = function install(Vue, options) {
4653

4754
this.pending = {
4855
path,
49-
stack,
56+
stack: replaceStack ? replaceStack : stack,
5057
data
5158
}
5259
},
@@ -83,13 +90,63 @@ const FrameRouter = function install(Vue, options) {
8390
navigatorLog(` *** NAVIGATOR::back(notify = ${notify}) ***`)
8491

8592
if (notify) {
86-
this.stack.pop()
87-
this.path = this.stack[this.stack.length - 1] || '/'
93+
if (!this.pending) {
94+
this.stack.pop()
95+
this.path = this.stack[this.stack.length - 1]
96+
97+
if (!this.path) {
98+
this.path = '/'
99+
this.stack = ['/']
100+
}
101+
} else {
102+
this._confirmPathChange()
103+
}
88104
} else {
105+
const replaceStack = this.stack.slice()
106+
replaceStack.pop()
107+
108+
this._setPending(
109+
this.stack[this.stack.length - 1] || '/',
110+
false,
111+
null,
112+
replaceStack
113+
)
89114
this.$navigateBack({
90115
frame: '__navigator_frame__'
91116
})
92117
}
118+
},
119+
/**
120+
* Tries to find the most recent entry matching the provided path in the backstack
121+
* and navigates back to it, if the path is not found a navigation will occur with
122+
* clearing the backStack
123+
* @param path
124+
*/
125+
backTo(path) {
126+
navigatorLog(` *** NAVIGATOR::backTo(path = ${path}) ***`)
127+
128+
const entry = navigator.frameVM.nativeView.backStack.find(entry => {
129+
return entry.entry.path === path
130+
})
131+
entry &&
132+
navigatorLog(` *** NAVIGATOR::backTo::FOUND_BACKSTACK_ENTRY ***`)
133+
134+
if (entry) {
135+
const index = this.stack
136+
.slice()
137+
.reverse()
138+
.findIndex(p => p === path)
139+
const actualIndex = this.stack.length - index
140+
const replaceStack = this.stack.slice()
141+
replaceStack.splice(actualIndex)
142+
this._setPending(path, false, null, replaceStack)
143+
this.$navigateBack({
144+
frame: '__navigator_frame__',
145+
entry: entry.entry
146+
})
147+
} else {
148+
this.replace(path)
149+
}
93150
}
94151
}
95152
})
@@ -109,6 +166,7 @@ const FrameRouter = function install(Vue, options) {
109166
Vue.component('FrameRouter', {
110167
created() {
111168
this.rendered = false
169+
navigator.frameVM = this
112170
},
113171
render(h) {
114172
if (!this.rendered) {
@@ -170,25 +228,86 @@ const DetailsPage = {
170228
<Button @tap="$navigator.replace('/details')" text="Replace to details" />
171229
172230
<Button @tap="$navigator.back()" text="Go back" />
231+
<Button @tap="$navigator.backTo('/')" text="Go back to Home" />
173232
</StackLayout>
174233
</Page>
175234
`
176235
}
177236

178-
Vue.use(FrameRouter, {
179-
routes: [
180-
{ path: '/', component: HomePage },
181-
{ path: '/details', component: DetailsPage }
182-
],
183-
debug: true
184-
})
237+
// LOGIN SCENARIO
185238

186-
new Vue({
187-
template: `
239+
if (SCENARIO === 'login') {
240+
const applicationSettings = require('tns-core-modules/application-settings')
241+
const LoginSCN__LoadingPage = {
242+
data() {
243+
return {
244+
isLoggedIn: applicationSettings.getBoolean('isLoggedIn', false)
245+
}
246+
},
247+
template: `
248+
<Page @loaded="$navigator.replace(isLoggedIn ? '/home' : '/login')" actionBarHidden="true" />
249+
`
250+
}
251+
const LoginSCN__HomePage = {
252+
template: `
253+
<Page>
254+
<StackLayout>
255+
<Button text="Do something (nav to home again...)" @tap="$navigator.push('/home')"/>
256+
<Button text="Log out" @tap="logout"/>
257+
</StackLayout>
258+
</Page>
259+
`,
260+
methods: {
261+
logout() {
262+
applicationSettings.setBoolean('isLoggedIn', false)
263+
this.$navigator.replace('/login')
264+
}
265+
}
266+
}
267+
const LoginSCN__LoginPage = {
268+
template: `
269+
<Page>
270+
<StackLayout>
271+
<Button text="Login" @tap="login"/>
272+
</StackLayout>
273+
</Page>
274+
`,
275+
methods: {
276+
login() {
277+
applicationSettings.setBoolean('isLoggedIn', true)
278+
this.$navigator.replace('/home')
279+
}
280+
}
281+
}
282+
283+
Vue.use(FrameRouter, {
284+
routes: [
285+
{ path: '/', component: LoginSCN__LoadingPage },
286+
{ path: '/home', component: LoginSCN__HomePage },
287+
{ path: '/login', component: LoginSCN__LoginPage }
288+
],
289+
debug: false
290+
})
291+
292+
new Vue({
293+
template: `<FrameRouter :transition="$navigator.path === '/' ? { name: 'fade', duration: 1 } : 'slide'"/>`
294+
}).$start()
295+
} else {
296+
Vue.use(FrameRouter, {
297+
routes: [
298+
{ path: '/', component: HomePage },
299+
{ path: '/details', component: DetailsPage }
300+
],
301+
debug: false
302+
})
303+
304+
new Vue({
305+
template: `
188306
<GridLayout rows="*, auto, auto">
189307
<FrameRouter row="0"/>
190308
<label :text="$navigator.$data.path" row="1" />
191309
<label :text="JSON.stringify($navigator.$data.stack, null, 2)" textWrap="true" row="2" />
192310
</GridLayout>
193311
`
194-
}).$start()
312+
}).$start()
313+
}

0 commit comments

Comments
 (0)