dojo / widget-core

:rocket: Dojo 2 - widget authoring system.
http://dojo.io
Other
34 stars 39 forks source link

Nesting components #483

Closed sebilasse closed 7 years ago

sebilasse commented 7 years ago

If I'd write webcomponents with this - how could I nest them ?

While I am trying to convert my existing webcomponents to dojo2 widgets I reached the following example :

<redaktor-details summary="an optional text">
  <img src="...">
  <p>Hello World</p>
</redaktor-details>

This component has no "logic" itself, it would render to something like https://codepen.io/sebilasse/pen/eZEdKM

rorticus commented 7 years ago

@sebilasse , as it states in README.md,

It should be noted that children nodes are removed from the DOM when widget instantiation occurs, and added as children to the widget instance.

Specifically what is happening is they are being added to the children instance variable of the widget. It is then the responsibility of the widget to perform the rendering of itself, and it's children.

Looking at the example you posted, you'd want something like this:

export interface RedaktorDetailsProperties extends WidgetProperties {
    summary?: string;
}

export default class RedaktorDetails extends WidgetBase<RedaktorDetailsProperties> {
    render() {
        const {summary = ''} = this.properties;
        const children: DNode[] = [...this.children];

        if (summary) {
            children.unshift(v('div', {innerHTML: summary}));
        }

        return v('label', children);
    }
}

which would give you a DOM like:

<redaktor-details summary="an optional text">
    <label>
        <div>an optional text></div>
        <img src="..." />
        <p>Hello World</p>
    </label>
</redaktor-details>

It's also worth noting that if you want to do custom initialization logic, such as grab child nodes and set them as properties instead of in children, you can provide an initialization function to access child nodes and set them as properties.

sebilasse commented 7 years ago

@rorticus @kitsonk Hm, that would mean: When I serverside-render my components that I have to take extra care of the children. Because once a component is rendered it would have other children than the provided ones.

A workaround could be to leave the provided children and put the serverside-rendered ones in <noscript> tags and let the client JS delete them first (?)

kitsonk commented 7 years ago

Right now, with maquette DOM cannot be re-used or subsumed. We have an outstanding PR with them and then we also have a change in flight to the Projector which will allow DOM to be subsumed (#487). I doubt it will totally solve this use case, but as of right now, any DOM that is already present will be dropped when the re-render occurs.

agubler commented 7 years ago

Nested components is now supported with updates to Maquette and widget-core.