Tidy up data binding
This commit is contained in:
parent
a6821814f8
commit
911fa31fe3
|
@ -24,7 +24,7 @@ import { cloneDeep, difference } from "lodash/fp"
|
|||
* @returns {Array.<BindableProperty>}
|
||||
*/
|
||||
export default function({ componentInstanceId, screen, components, tables }) {
|
||||
const walkResult = walk({
|
||||
const result = walk({
|
||||
// cloning so we are free to mutate props (e.g. by adding _contexts)
|
||||
instance: cloneDeep(screen.props),
|
||||
targetId: componentInstanceId,
|
||||
|
@ -33,13 +33,10 @@ export default function({ componentInstanceId, screen, components, tables }) {
|
|||
})
|
||||
|
||||
return [
|
||||
...walkResult.bindableInstances
|
||||
.filter(isInstanceInSharedContext(walkResult))
|
||||
.map(componentInstanceToBindable(walkResult)),
|
||||
|
||||
...(walkResult.target?._contexts
|
||||
.map(contextToBindables(tables, walkResult))
|
||||
.flat() ?? []),
|
||||
...result.bindableInstances
|
||||
.filter(isInstanceInSharedContext(result))
|
||||
.map(componentInstanceToBindable),
|
||||
...(result.target?._contexts.map(contextToBindables(tables)).flat() ?? []),
|
||||
]
|
||||
}
|
||||
|
||||
|
@ -53,26 +50,18 @@ const isInstanceInSharedContext = walkResult => i =>
|
|||
|
||||
// turns a component instance prop into binding expressions
|
||||
// used by the UI
|
||||
const componentInstanceToBindable = walkResult => i => {
|
||||
const lastContext =
|
||||
i.instance._contexts.length &&
|
||||
i.instance._contexts[i.instance._contexts.length - 1]
|
||||
const contextParentPath = lastContext
|
||||
? getParentPath(walkResult, lastContext)
|
||||
: ""
|
||||
|
||||
const componentInstanceToBindable = i => {
|
||||
return {
|
||||
type: "instance",
|
||||
instance: i.instance,
|
||||
// how the binding expression persists, and is used in the app at runtime
|
||||
runtimeBinding: `${contextParentPath}${i.instance._id}.${i.prop}`,
|
||||
runtimeBinding: `${i.instance._id}`,
|
||||
// how the binding exressions looks to the user of the builder
|
||||
readableBinding: `${i.instance._instanceName}`,
|
||||
}
|
||||
}
|
||||
|
||||
const contextToBindables = (tables, walkResult) => context => {
|
||||
const contextParentPath = getParentPath(walkResult, context)
|
||||
const contextToBindables = tables => context => {
|
||||
const tableId = context.table?.tableId ?? context.table
|
||||
const table = tables.find(table => table._id === tableId)
|
||||
let schema =
|
||||
|
@ -98,7 +87,7 @@ const contextToBindables = (tables, walkResult) => context => {
|
|||
fieldSchema,
|
||||
instance: context.instance,
|
||||
// how the binding expression persists, and is used in the app at runtime
|
||||
runtimeBinding: `${contextParentPath}data.${runtimeBoundKey}`,
|
||||
runtimeBinding: `${context.instance._id}.${runtimeBoundKey}`,
|
||||
// how the binding expressions looks to the user of the builder
|
||||
readableBinding: `${context.instance._instanceName}.${table.name}.${key}`,
|
||||
// table / view info
|
||||
|
@ -118,20 +107,6 @@ const contextToBindables = (tables, walkResult) => context => {
|
|||
)
|
||||
}
|
||||
|
||||
const getParentPath = (walkResult, context) => {
|
||||
// describes the number of "parent" in the path
|
||||
// clone array first so original array is not mtated
|
||||
const contextParentNumber = [...walkResult.target._contexts]
|
||||
.reverse()
|
||||
.indexOf(context)
|
||||
|
||||
return (
|
||||
new Array(contextParentNumber).fill("parent").join(".") +
|
||||
// trailing . if has parents
|
||||
(contextParentNumber ? "." : "")
|
||||
)
|
||||
}
|
||||
|
||||
const walk = ({ instance, targetId, components, tables, result }) => {
|
||||
if (!result) {
|
||||
result = {
|
||||
|
|
|
@ -12,10 +12,7 @@ export function readableToRuntimeBinding(bindableProperties, textWithBindings) {
|
|||
return boundValue === `{{ ${readableBinding} }}`
|
||||
})
|
||||
if (binding) {
|
||||
result = textWithBindings.replace(
|
||||
boundValue,
|
||||
`{{ ${binding.runtimeBinding} }}`
|
||||
)
|
||||
result = result.replace(boundValue, `{{ ${binding.runtimeBinding} }}`)
|
||||
}
|
||||
})
|
||||
return result
|
||||
|
|
|
@ -46,7 +46,7 @@ export default `<html>
|
|||
|
||||
selectedComponentStyle = document.createElement('style');
|
||||
document.head.appendChild(selectedComponentStyle)
|
||||
var selectedCss = '[data-bb-id="' + data.selectedComponentType + '-' + data.selectedComponentId + '"]' + '{border:2px solid #0055ff !important;}'
|
||||
var selectedCss = '[data-bb-id="' + data.selectedComponentId + '"]' + '{border:2px solid #0055ff !important;}'
|
||||
selectedComponentStyle.appendChild(document.createTextNode(selectedCss))
|
||||
|
||||
styles = document.createElement('style')
|
||||
|
|
|
@ -30,14 +30,13 @@
|
|||
// Extract component definition info
|
||||
const componentName = extractComponentName(definition._component)
|
||||
const constructor = getComponentConstructor(componentName)
|
||||
const id = `${componentName}-${definition._id}`
|
||||
const componentProps = extractValidProps(definition)
|
||||
const dataContext = getContext("data")
|
||||
const enrichedProps = dataContext.actions.enrichDataBindings(componentProps)
|
||||
const children = definition._children
|
||||
|
||||
// Set style context to be consumed by component
|
||||
setContext("style", { ...definition._styles, id })
|
||||
// Set contexts to be consumed by component
|
||||
setContext("style", { ...definition._styles, id: definition._id })
|
||||
$: console.log("Rendering: " + componentName)
|
||||
</script>
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
// Get current contexts
|
||||
const dataContext = getContext("data")
|
||||
const { id } = getContext("style")
|
||||
|
||||
// Clone current context to this context
|
||||
const newDataContext = createDataContextStore($dataContext)
|
||||
|
@ -14,7 +15,7 @@
|
|||
// Add additional layer to context
|
||||
let loaded = false
|
||||
onMount(() => {
|
||||
newDataContext.actions.addContext(row)
|
||||
newDataContext.actions.addContext(row, id)
|
||||
loaded = true
|
||||
})
|
||||
</script>
|
||||
|
|
|
@ -3,7 +3,6 @@ import { enrichDataBinding } from "../utils"
|
|||
import { cloneDeep } from "lodash/fp"
|
||||
|
||||
const initialValue = {
|
||||
parent: null,
|
||||
data: null,
|
||||
}
|
||||
|
||||
|
@ -12,15 +11,12 @@ export const createDataContextStore = existingContext => {
|
|||
const store = writable(initial)
|
||||
|
||||
// Adds a context layer to the data context tree
|
||||
const addContext = row => {
|
||||
const addContext = (row, componentId) => {
|
||||
store.update(state => {
|
||||
if (state.data) {
|
||||
state.parent = {
|
||||
parent: state.parent,
|
||||
data: state.data,
|
||||
}
|
||||
if (row && componentId) {
|
||||
state[componentId] = row
|
||||
state.data = row
|
||||
}
|
||||
state.data = row
|
||||
return state
|
||||
})
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue