[IMP] component: better detection for dynamic component change

Before this commit, Owl could not detect that the underlying component
in a template such as <t t-component="{{state.child}}"/> was changing,
if the two components have the same tag as root element.

This is because the reconciliation is done at the vdom level, which does
not know about components.  To solve this, one could use a t-key to make
sure owl can make the difference.

With this commit, we can simply use our knowledge of the fact that we are
dealing with a dynamic component and autogenerate a suitable key.

closes #623
This commit is contained in:
Géry Debongnie
2021-07-03 22:30:21 +02:00
committed by aab-odoo
parent 27629cedfa
commit 17ae1d06c4
3 changed files with 93 additions and 11 deletions
+24
View File
@@ -1246,6 +1246,30 @@ describe("composition", () => {
expect(fixture.innerHTML).toBe("<div>child b</div>");
});
test("can switch between dynamic components without the need for a t-key", async () => {
class A extends Component {
static template = xml`<span>child a</span>`;
}
class B extends Component {
static template = xml`<span>child b</span>`;
}
class App extends Component {
static template = xml`
<div>
<t t-component="{{state.child}}"/>
</div>`;
static components = { A, B };
state = useState({ child: "A" });
}
const app = await mount(App, { target: fixture });
expect(fixture.innerHTML).toBe("<div><span>child a</span></div>");
app.state.child = "B";
await nextTick();
expect(fixture.innerHTML).toBe("<div><span>child b</span></div>");
expect(QWeb.TEMPLATES[App.template].fn.toString()).toMatchSnapshot();
});
test("don't fallback to global registry if widget defined locally", async () => {
QWeb.registerComponent("WidgetB", WidgetB); // should not use this widget
env.qweb.addTemplate("ParentWidget", `<div><t t-component="WidgetB"/></div>`);