diff --git a/src/portal.ts b/src/portal.ts index 68f654e9..7085b482 100644 --- a/src/portal.ts +++ b/src/portal.ts @@ -1,7 +1,6 @@ -import type { ComponentNode } from "./component/component_node"; -import { Component } from "./component/component"; import { xml } from "./app/template_set"; import { BDom, text, VNode } from "./blockdom"; +import { Component } from "./component/component"; const VText: any = text("").constructor; @@ -60,12 +59,9 @@ export class Portal extends Component { slots: true, }; - constructor(props: any, env: any, node: ComponentNode) { - super(props, env, node); - node._render = function (fiber: any) { - const bdom = new VPortal(props.target, this.renderFn()); - fiber.bdom = bdom; - fiber.root.counter--; - }; + setup() { + const node = this.__owl__; + const renderFn = node.renderFn; + node.renderFn = () => new VPortal(this.props.target, renderFn()); } } diff --git a/tests/misc/__snapshots__/portal.test.ts.snap b/tests/misc/__snapshots__/portal.test.ts.snap index c5b09eee..36119058 100644 --- a/tests/misc/__snapshots__/portal.test.ts.snap +++ b/tests/misc/__snapshots__/portal.test.ts.snap @@ -409,6 +409,45 @@ exports[`Portal portal's parent's env is not polluted 2`] = ` }" `; +exports[`Portal simple catchError with portal 1`] = ` +"function anonymous(bdom, helpers +) { + let { text, createBlock, list, multi, html, toggler, component, comment } = bdom; + + let block1 = createBlock(\`
\`); + + return function template(ctx, node, key = \\"\\") { + let b2,b3; + if (ctx['error']) { + b2 = text(\`Error\`); + } else { + b3 = component(\`Boom\`, {}, key + \`__1\`, node, ctx); + } + return block1([], [b2, b3]); + } +}" +`; + +exports[`Portal simple catchError with portal 2`] = ` +"function anonymous(bdom, helpers +) { + let { text, createBlock, list, multi, html, toggler, component, comment } = bdom; + + let block1 = createBlock(\`
1
\`); + let block2 = createBlock(\`

\`); + + function slot1(ctx, node, key = \\"\\") { + let txt1 = ctx['a'].b.c; + return block2([txt1]); + } + + return function template(ctx, node, key = \\"\\") { + let b3 = component(\`Portal\`, {target: '#outside',slots: {'default': {__render: slot1, __ctx: ctx}}}, key + \`__1\`, node, ctx); + return block1([], [b3]); + } +}" +`; + exports[`Portal with target in template (after portal) 1`] = ` "function anonymous(bdom, helpers ) { diff --git a/tests/misc/portal.test.ts b/tests/misc/portal.test.ts index 2168681f..9baf12f3 100644 --- a/tests/misc/portal.test.ts +++ b/tests/misc/portal.test.ts @@ -68,6 +68,43 @@ describe("Portal", () => { expect(fixture.innerHTML).toBe('

2

1
'); }); + test("simple catchError with portal", async () => { + class Boom extends Component { + static components = { Portal }; + static template = xml` +
+ 1 + +

+
+
`; + } + + class Parent extends Component { + static template = xml` +
+ Error + + + +
`; + static components = { Boom }; + + error: any = false; + + setup() { + onError((err) => { + this.error = err; + this.render(); + }); + } + } + addOutsideDiv(fixture); + + await mount(Parent, fixture); + expect(fixture.innerHTML).toBe('
Error
'); + }); + test("basic use of portal in dev mode", async () => { class Parent extends Component { static components = { Portal };