allow new widgets to be mount in mounted hook

This commit is contained in:
Géry Debongnie
2019-01-24 22:17:06 +01:00
parent dbada21890
commit c1dd38bf03
2 changed files with 31 additions and 2 deletions
+1 -1
View File
@@ -56,7 +56,7 @@ export class Widget<T extends WEnv> {
if (document.body.contains(target)) { if (document.body.contains(target)) {
this.visitSubTree(w => { this.visitSubTree(w => {
if (!w.isMounted) { if (!w.isMounted && this.el!.contains(w.el)) {
w.isMounted = true; w.isMounted = true;
w.mounted(); w.mounted();
} }
+30 -1
View File
@@ -157,7 +157,7 @@ describe("lifecycle hooks", () => {
let childMounted = false; let childMounted = false;
class ParentWidget extends Widget<TestEnv> { class ParentWidget extends Widget<TestEnv> {
name = "a"; name = "a";
template = `<div>Hello<t t-widget="child"/></div>`; template = `<div><t t-widget="child"/></div>`;
widgets = { child: ChildWidget }; widgets = { child: ChildWidget };
mounted() { mounted() {
expect(childMounted).toBe(false); expect(childMounted).toBe(false);
@@ -216,6 +216,35 @@ describe("lifecycle hooks", () => {
expect(hookCounter).toBe(2); expect(hookCounter).toBe(2);
target.remove(); target.remove();
}); });
test("mounted hook is correctly called on subwidgets created in mounted hook", async done => {
// the issue here is that the parent widget creates in the
// mounted hook a new widget, which means that it modifies
// in place its list of children. But this list of children is currently
// being visited, so the mount action of the parent could cause a mount
// action of the new child widget, even though it is not ready yet.
expect.assertions(1);
const target = document.createElement("div");
document.body.appendChild(target);
class ParentWidget extends Widget<TestEnv> {
name = "a";
mounted() {
const child = new ChildWidget(this);
child.mount(this.el!);
}
}
class ChildWidget extends Widget<TestEnv> {
mounted() {
expect(this.el).toBeTruthy();
target.remove();
done();
}
}
const widget = makeWidget(ParentWidget);
await widget.mount(target);
});
}); });
describe("destroy method", () => { describe("destroy method", () => {