mirror of
https://github.com/odoo/owl.git
synced 2025-10-06 19:59:41 +07:00
implement updateEnv feature
This commit is contained in:
@@ -196,6 +196,23 @@ export class Component<
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is the correct way to update the environment of a widget. Doing
|
||||
* this will cause a full rerender of the widget and its children, so this is
|
||||
* an operation that should not be done frequently.
|
||||
*
|
||||
* A good usecase for updating the environment would be to update some mostly
|
||||
* static config keys, such as a boolean to determine if we are in mobile
|
||||
* mode or not.
|
||||
*/
|
||||
async updateEnv(nextEnv: Partial<T>): Promise<void> {
|
||||
if (this.__widget__.parent && this.__widget__.parent.env === this.env) {
|
||||
this.env = Object.create(this.env);
|
||||
}
|
||||
Object.assign(this.env, nextEnv);
|
||||
return this.render();
|
||||
}
|
||||
|
||||
async updateProps(nextProps: Props): Promise<void> {
|
||||
if (nextProps === this.__widget__.renderProps) {
|
||||
await this.__widget__.renderPromise;
|
||||
|
||||
+64
-1
@@ -36,7 +36,7 @@ afterEach(() => {
|
||||
fixture.remove();
|
||||
});
|
||||
|
||||
class Widget extends Component<Env, any, any> {}
|
||||
class Widget extends Component<any, any, any> {}
|
||||
|
||||
function children(w: Widget): Widget[] {
|
||||
const childrenMap = w.__widget__.children;
|
||||
@@ -1086,3 +1086,66 @@ describe("async rendering", () => {
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe("updating environment", () => {
|
||||
test("can update widget env", async () => {
|
||||
const widget = new Widget(env);
|
||||
expect(widget.env).toBe(env);
|
||||
await widget.updateEnv(<any>{ somekey: 4 });
|
||||
expect(widget.env).toBe(env);
|
||||
expect((<any>widget).env.somekey).toBe(4);
|
||||
});
|
||||
|
||||
test("updating child env does not modify parent env", async () => {
|
||||
class ParentWidget extends Widget {
|
||||
inlineTemplate = `<div><t t-widget="child"/></div>`;
|
||||
widgets = { child: Widget };
|
||||
}
|
||||
const parent = new ParentWidget(env);
|
||||
await parent.mount(fixture);
|
||||
const child = children(parent)[0];
|
||||
expect(child.env).toBe(parent.env);
|
||||
await child.updateEnv(<any>{ somekey: 4 });
|
||||
expect(child.env).not.toBe(parent.env);
|
||||
expect((<any>parent).env.somekey).toBeUndefined();
|
||||
});
|
||||
|
||||
test("updating parent env does modify child env", async () => {
|
||||
class ParentWidget extends Widget {
|
||||
inlineTemplate = `<div><t t-widget="child"/></div>`;
|
||||
widgets = { child: Widget };
|
||||
}
|
||||
const parent = new ParentWidget(env);
|
||||
await parent.mount(fixture);
|
||||
const child = children(parent)[0];
|
||||
expect(child.env.somekey).toBeUndefined();
|
||||
await parent.updateEnv({ somekey: 4 });
|
||||
expect(child.env.somekey).toBe(4);
|
||||
});
|
||||
|
||||
test("updating parent env does modify child env, part 2", async () => {
|
||||
class ParentWidget extends Widget {
|
||||
inlineTemplate = `<div><t t-widget="child"/></div>`;
|
||||
widgets = { child: Widget };
|
||||
}
|
||||
const parent = new ParentWidget(env);
|
||||
await parent.mount(fixture);
|
||||
const child = children(parent)[0];
|
||||
expect(child.env.somekey).toBeUndefined();
|
||||
await child.updateEnv({ somekey: 4 });
|
||||
await parent.updateEnv({ someotherkey: 4 });
|
||||
expect(child.env.someotherkey).toBe(4);
|
||||
});
|
||||
|
||||
test("updating env force a rerender", async () => {
|
||||
class TestWidget extends Widget {
|
||||
inlineTemplate = `<div><t t-esc="env.someKey"/></div>`;
|
||||
}
|
||||
(<any>env).someKey = "hey";
|
||||
const widget = new TestWidget(env);
|
||||
await widget.mount(fixture);
|
||||
expect(fixture.innerHTML).toBe("<div>hey</div>");
|
||||
await widget.updateEnv(<any>{ someKey: "rerendered" });
|
||||
expect(fixture.innerHTML).toBe("<div>rerendered</div>");
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user