8000 feat: support async component with showModal · Yellowbox-AU/nativescript-vue@35510e6 · GitHub
[go: up one dir, main page]

Skip to content

Commit 35510e6

Browse files
committed
feat: support async component with showModal
1 parent 48edf28 commit 35510e6

File tree

1 file changed

+42
-3
lines changed

1 file changed

+42
-3
lines changed

platform/nativescript/plugins/modal-plugin.js

Lines changed: 42 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { isObject, isDef, isPrimitive } from 'shared/util'
22
import { updateDevtools } from '../util'
33
import { VUE_ELEMENT_REF } from '../renderer/ElementNode'
4+
import { Placeholder, Page } from '@nativescript/core'
45

56
let sequentialCounter = 0
67

@@ -61,7 +62,7 @@ export default {
6162
})
6263

6364
Vue.prototype.$showModal = function (component, options) {
64-
return new Promise(resolve => {
65+
return new Promise(async resolve => {
6566
let resolved = false
6667
const closeCb = data => {
6768
if (resolved) return
@@ -99,8 +100,46 @@ export default {
99100
props: options.props,
100101
key: serializeModalOptions(options)
101102
})
102-
})
103-
const modalPage = navEntryInstance.$mount().$el.nativeView
103+
}).$mount()
104+
const componentName =
105+
(typeof component === 'string'
106+
? component
107+
: component.name ||
108+
(component.__file && component.__file.match(/\w+(?=\.vue)/))) ||
109+
'Unknown'
110+
let modalPage = navEntryInstance.$el.nativeView
111+
// This check's purpose is to determine if we are showing an async component.
112+
if (modalPage instanceof Placeholder) {
113+
console.log(
114+
`Modal destination component ${
115+
componentName || 'Unknown'
116+
} rendered a <Placeholder> at its root. Waiting for update with <Page> before showing modal...`
117+
)
118+
// Wait for update event and make sure <Page> is rendered as root node
119+
modalPage = await new Promise((resolve, reject) => {
120+
let updatedFn = function () {
121+
if (this.$el.nativeView instanceof Page) {
122+
resolve(this.$el.nativeView)
123+
this.$off('hook:updated', updatedFn)
124+
} else if (!(this.$el.nativeView instanceof Placeholder)) {
125+
reject(
126+
new Error(
127+
`Root element of showModal destination component ("${componentName}") must be a <Page>, got <${this.$el.nativeView.constructor.name}>`
128+
)
129+
)
130+
navEntryInstance.$destroy()
131+
this.$off('hook:updated', updatedFn)
132+
}
133+
}
134+
navEntryInstance.$on('hook:updated', updatedFn)
135+
})
136+
} else if (!(modalPage instanceof Page)) {
137+
setTimeout(() => navEntryInstance.$destroy(), 0)
138+
throw new Error(
139+
`Root element of showModal destination component ("${componentName}") must be a <Page>, got <${modalPage.constructor.name}>`
140+
)
141+
}
142+
104143
updateDevtools()
105144

106145
getTargetView(options.target).showModal(modalPage, options)

0 commit comments

Comments
 (0)
0