Budibase is an open-source low-code platform for creating internal apps in minutes. Supports PostgreSQL, MySQL, MSSQL, MongoDB, Rest API, Docker, K8s 🚀
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

88 lines
2.5 KiB

import renderTemplateString from "../state/renderTemplateString"
import appStore from "../state/store"
import hasBinding from "../state/hasBinding"
export const prepareRenderComponent = ({
ComponentConstructor,
htmlElement,
anchor,
props,
parentNode,
contextStoreKey,
}) => {
const thisNode = createTreeNode()
thisNode.parentNode = parentNode
thisNode.props = props
thisNode.contextStoreKey = contextStoreKey
// the treeNode is first created (above), and then this
// render method is add. The treeNode is returned, and
// render is called later (in attachChildren)
thisNode.render = initialProps => {
thisNode.component = new ComponentConstructor({
target: htmlElement,
props: initialProps,
hydrate: false,
anchor,
})
// finds the root element of the component, which was created by the contructor above
// we use this later to attach a className to. This is how styles
// are applied by the builder
thisNode.rootElement = htmlElement.children[htmlElement.children.length - 1]
let [componentName] = props._component.match(/[a-z]*$/)
if (props._id && thisNode.rootElement) {
thisNode.rootElement.classList.add(`${componentName}-${props._id}`)
}
// make this node listen to the store
if (thisNode.stateBound) {
const unsubscribe = appStore.subscribe(state => {
const storeBoundProps = Object.keys(initialProps._bb.props).filter(p =>
hasBinding(initialProps._bb.props[p])
)
if (storeBoundProps.length > 0) {
const toSet = {}
for (let prop of storeBoundProps) {
const propValue = initialProps._bb.props[prop]
toSet[prop] = renderTemplateString(propValue, state)
}
thisNode.component.$set(toSet)
}
}, thisNode.contextStoreKey)
thisNode.unsubscribe = unsubscribe
}
}
return thisNode
}
export const createTreeNode = () => ({
context: {},
props: {},
rootElement: null,
parentNode: null,
children: [],
bindings: [],
component: null,
unsubscribe: () => {},
render: () => {},
get destroy() {
const node = this
return () => {
if (node.children) {
// destroy children first - from leaf nodes up
for (let child of node.children) {
child.destroy()
}
}
if (node.unsubscribe) node.unsubscribe()
if (node.component && node.component.$destroy) node.component.$destroy()
for (let onDestroyItem of node.onDestroy) {
onDestroyItem()
}
}
},
onDestroy: [],
})