mirror of https://github.com/Budibase/budibase.git
Browse Source
* removed binding references to array type * refactored initialiseChildren into seperate file * render function, with code blocks - tested simple cases * few mores tests for control flow * md components - getting TestApp to work * new render wrapper - bug fixpull/4023/head
committed by
GitHub
8 changed files with 248 additions and 174 deletions
@ -0,0 +1,67 @@ |
|||||
|
import { |
||||
|
setupBinding |
||||
|
} from "../state/stateBinding"; |
||||
|
import { |
||||
|
split, |
||||
|
last |
||||
|
} from "lodash/fp"; |
||||
|
import { $ } from "../core/common"; |
||||
|
import { renderComponent } from "./renderComponent"; |
||||
|
|
||||
|
export const _initialiseChildren = (initialiseOpts) => |
||||
|
(childrenProps, htmlElement, context, anchor=null) => { |
||||
|
|
||||
|
const { uiFunctions, bb, coreApi, |
||||
|
store, componentLibraries, |
||||
|
appDefinition, parentContext, hydrate } = initialiseOpts; |
||||
|
|
||||
|
const childComponents = []; |
||||
|
|
||||
|
if(hydrate) { |
||||
|
while (htmlElement.firstChild) { |
||||
|
htmlElement.removeChild(htmlElement.firstChild); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
for(let childProps of childrenProps) { |
||||
|
|
||||
|
const {componentName, libName} = splitName(childProps._component); |
||||
|
|
||||
|
if(!componentName || !libName) return; |
||||
|
|
||||
|
const {initialProps, bind} = setupBinding( |
||||
|
store, childProps, coreApi, |
||||
|
context || parentContext, appDefinition.appRootPath); |
||||
|
|
||||
|
/// here needs to go inside renderComponent ???
|
||||
|
const componentProps = { |
||||
|
...initialProps, |
||||
|
_bb:bb(context || parentContext, childProps) |
||||
|
}; |
||||
|
|
||||
|
const componentConstructor = componentLibraries[libName][componentName]; |
||||
|
|
||||
|
const {component} = renderComponent({ |
||||
|
componentConstructor,uiFunctions, |
||||
|
htmlElement, anchor, |
||||
|
parentContext, componentProps}); |
||||
|
|
||||
|
|
||||
|
bind(component); |
||||
|
childComponents.push(component); |
||||
|
} |
||||
|
|
||||
|
return childComponents; |
||||
|
} |
||||
|
|
||||
|
const splitName = fullname => { |
||||
|
const componentName = $(fullname, [ |
||||
|
split("/"), |
||||
|
last |
||||
|
]); |
||||
|
|
||||
|
const libName =fullname.substring( |
||||
|
0, fullname.length - componentName.length - 1); |
||||
|
|
||||
|
return {libName, componentName}; |
||||
|
} |
||||
@ -0,0 +1,41 @@ |
|||||
|
|
||||
|
export const renderComponent = ({ |
||||
|
componentConstructor, uiFunctions, |
||||
|
htmlElement, anchor, parentContext, |
||||
|
componentProps}) => { |
||||
|
|
||||
|
const func = componentProps._id |
||||
|
? uiFunctions[componentProps._id] |
||||
|
: undefined; |
||||
|
|
||||
|
let component; |
||||
|
let componentContext; |
||||
|
const render = (context) => { |
||||
|
|
||||
|
if(context) { |
||||
|
componentContext = {...componentContext}; |
||||
|
componentContext.$parent = parentContext; |
||||
|
} else { |
||||
|
componentContext = parentContext; |
||||
|
} |
||||
|
|
||||
|
component = new componentConstructor({ |
||||
|
target: htmlElement, |
||||
|
props: componentProps, |
||||
|
hydrate:false, |
||||
|
anchor |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
if(func) { |
||||
|
func(render, parentContext); |
||||
|
} else { |
||||
|
render(); |
||||
|
} |
||||
|
|
||||
|
return ({ |
||||
|
context: componentContext, |
||||
|
component |
||||
|
}); |
||||
|
} |
||||
|
|
||||
@ -0,0 +1,74 @@ |
|||||
|
import { load } from "./testAppDef"; |
||||
|
|
||||
|
describe("controlFlow", () => { |
||||
|
|
||||
|
it("should display simple div, with always true render function", async () => { |
||||
|
|
||||
|
const {dom} = await load({ |
||||
|
_component: "testlib/div", |
||||
|
className: "my-test-class", |
||||
|
_id: "always_render" |
||||
|
}); |
||||
|
|
||||
|
expect(dom.window.document.body.children.length).toBe(1); |
||||
|
const child = dom.window.document.body.children[0]; |
||||
|
expect(child.className).toBe("my-test-class"); |
||||
|
|
||||
|
}) |
||||
|
|
||||
|
it("should not display div, with always false render function", async () => { |
||||
|
|
||||
|
const {dom} = await load({ |
||||
|
_component: "testlib/div", |
||||
|
className: "my-test-class", |
||||
|
_id: "never_render" |
||||
|
}); |
||||
|
|
||||
|
expect(dom.window.document.body.children.length).toBe(0); |
||||
|
|
||||
|
}) |
||||
|
|
||||
|
it("should display 3 divs in a looped render function", async () => { |
||||
|
|
||||
|
const {dom} = await load({ |
||||
|
_component: "testlib/div", |
||||
|
className: "my-test-class", |
||||
|
_id: "three_clones" |
||||
|
}); |
||||
|
|
||||
|
expect(dom.window.document.body.children.length).toBe(3); |
||||
|
|
||||
|
const child0 = dom.window.document.body.children[0]; |
||||
|
expect(child0.className).toBe("my-test-class"); |
||||
|
|
||||
|
const child1 = dom.window.document.body.children[1]; |
||||
|
expect(child1.className).toBe("my-test-class"); |
||||
|
|
||||
|
const child2 = dom.window.document.body.children[2]; |
||||
|
expect(child2.className).toBe("my-test-class"); |
||||
|
|
||||
|
}) |
||||
|
|
||||
|
it("should display 3 div, in a looped render, as children", async () => { |
||||
|
const {dom} = await load({ |
||||
|
_component: "testlib/div", |
||||
|
_children: [ |
||||
|
{ |
||||
|
_component: "testlib/div", |
||||
|
className: "my-test-class", |
||||
|
_id: "three_clones" |
||||
|
} |
||||
|
] |
||||
|
}); |
||||
|
|
||||
|
expect(dom.window.document.body.children.length).toBe(1); |
||||
|
|
||||
|
const rootDiv = dom.window.document.body.children[0]; |
||||
|
expect(rootDiv.children.length).toBe(3); |
||||
|
|
||||
|
expect(rootDiv.children[0].className).toBe("my-test-class"); |
||||
|
expect(rootDiv.children[1].className).toBe("my-test-class"); |
||||
|
expect(rootDiv.children[2].className).toBe("my-test-class"); |
||||
|
}) |
||||
|
|
||||
|
}); |
||||
Loading…
Reference in new issue