mirror of
https://github.com/odoo/owl.git
synced 2025-10-06 19:59:41 +07:00
[FIX] component: allow fragments in method mount
It is now possible to mount components in fragments closes #494
This commit is contained in:
@@ -239,7 +239,7 @@ We explain here all the public methods of the `Component` class.
|
||||
|
||||
- **`mount(target)`** (async): this is the main way a
|
||||
component is added to the DOM: the root component is mounted to a target
|
||||
HTMLElement. Obviously, this is asynchronous, since each children need to be
|
||||
HTMLElement (or document fragment). Obviously, this is asynchronous, since each children need to be
|
||||
created as well. Most applications will need to call `mount` exactly once, on
|
||||
the root component.
|
||||
|
||||
@@ -247,6 +247,20 @@ We explain here all the public methods of the `Component` class.
|
||||
automatically re-rendered to ensure that changes in its state (or something
|
||||
in the environment, or in the store, or ...) will be taken into account.
|
||||
|
||||
If a component is mounted inside an element or a fragment which is not in the
|
||||
DOM, then it will be rendered fully, but not active: the `mounted` hooks will
|
||||
not be called. This is sometimes useful if we want to load an application in
|
||||
memory. In that case, we need to mount the root component again in an element
|
||||
which is in the DOM:
|
||||
|
||||
```js
|
||||
const app = new App();
|
||||
await app.mount(document.createDocumentFragment());
|
||||
// app is rendered in memory, but not active
|
||||
await app.mount(document.body);
|
||||
// app is now visible
|
||||
```
|
||||
|
||||
- **`unmount()`**: in case a component needs to be detached/removed from the DOM, this
|
||||
method can be used. Most applications should not call `unmount`, this is more
|
||||
useful to the underlying component system.
|
||||
|
||||
@@ -281,12 +281,12 @@ export class Component<T extends Env, Props extends {}> {
|
||||
*
|
||||
* Note that a component can be mounted an unmounted several times
|
||||
*/
|
||||
async mount(target: HTMLElement): Promise<void> {
|
||||
async mount(target: HTMLElement | DocumentFragment): Promise<void> {
|
||||
const __owl__ = this.__owl__;
|
||||
if (__owl__.isMounted) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
if (!(target instanceof HTMLElement)) {
|
||||
if (!(target instanceof HTMLElement || target instanceof DocumentFragment)) {
|
||||
let message = `Component '${this.constructor.name}' cannot be mounted: the target is not a valid DOM node.`;
|
||||
message += `\nMaybe the DOM is not ready yet? (in that case, you can use owl.utils.whenReady)`;
|
||||
throw new Error(message);
|
||||
|
||||
@@ -91,6 +91,17 @@ describe("basic widget properties", () => {
|
||||
expect(fixture.innerHTML).toBe("<div>content</div>");
|
||||
});
|
||||
|
||||
test("can be mounted on a documentFragment", async () => {
|
||||
class SomeWidget extends Component<any, any> {
|
||||
static template = xml`<div>content</div>`;
|
||||
}
|
||||
const widget = new SomeWidget();
|
||||
await widget.mount(document.createDocumentFragment());
|
||||
expect(fixture.innerHTML).toBe("");
|
||||
await widget.mount(fixture);
|
||||
expect(fixture.innerHTML).toBe("<div>content</div>");
|
||||
});
|
||||
|
||||
test("display a nice message if mounted on a non existing node", async () => {
|
||||
class SomeWidget extends Component<any, any> {
|
||||
static template = xml`<div>content</div>`;
|
||||
|
||||
Reference in New Issue
Block a user