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;
|
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> {
|
async updateProps(nextProps: Props): Promise<void> {
|
||||||
if (nextProps === this.__widget__.renderProps) {
|
if (nextProps === this.__widget__.renderProps) {
|
||||||
await this.__widget__.renderPromise;
|
await this.__widget__.renderPromise;
|
||||||
|
|||||||
+64
-1
@@ -36,7 +36,7 @@ afterEach(() => {
|
|||||||
fixture.remove();
|
fixture.remove();
|
||||||
});
|
});
|
||||||
|
|
||||||
class Widget extends Component<Env, any, any> {}
|
class Widget extends Component<any, any, any> {}
|
||||||
|
|
||||||
function children(w: Widget): Widget[] {
|
function children(w: Widget): Widget[] {
|
||||||
const childrenMap = w.__widget__.children;
|
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