diff --git a/src/qweb/base_directives.ts b/src/qweb/base_directives.ts index dd418b3b..74817be0 100644 --- a/src/qweb/base_directives.ts +++ b/src/qweb/base_directives.ts @@ -283,9 +283,7 @@ QWeb.addDirective({ } if (shouldWarn) { console.warn( - `Directive t-foreach should always be used with a t-key! (in template: '${ - ctx.templateName - }')` + `Directive t-foreach should always be used with a t-key! (in template: '${ctx.templateName}')` ); } nodeCopy.removeAttribute("t-foreach"); diff --git a/src/qweb/extensions.ts b/src/qweb/extensions.ts index 0b28b6e2..9070ab22 100644 --- a/src/qweb/extensions.ts +++ b/src/qweb/extensions.ts @@ -230,9 +230,7 @@ QWeb.addDirective({ ctx.addLine(`const slot${slotKey} = this.slots[context.__owl__.slotId + '_' + '${value}'];`); ctx.addIf(`slot${slotKey}`); ctx.addLine( - `slot${slotKey}(context.__owl__.parent, Object.assign({}, extra, {parentNode: c${ - ctx.parentNode - }, vars: extra.vars, parent: owner}));` + `slot${slotKey}(context.__owl__.parent, Object.assign({}, extra, {parentNode: c${ctx.parentNode}, vars: extra.vars, parent: owner}));` ); ctx.closeIf(); return true; diff --git a/src/qweb/qweb.ts b/src/qweb/qweb.ts index 6b850b3e..968b4be1 100644 --- a/src/qweb/qweb.ts +++ b/src/qweb/qweb.ts @@ -1,6 +1,7 @@ import { EventBus } from "../core/event_bus"; import { h, patch, VNode } from "../vdom/index"; import { Context } from "./context"; +import { shallowEqual } from "../utils"; /** * Owl QWeb Engine @@ -92,14 +93,7 @@ const UTILS: Utils = { } return expr; }, - shallowEqual(p1, p2) { - for (let k in p1) { - if (p1[k] !== p2[k]) { - return false; - } - } - return true; - } + shallowEqual }; function parseXML(xml: string): Document { @@ -212,7 +206,7 @@ export class QWeb extends EventBus { * template, with the name given by the t-name attribute. */ addTemplates(xmlstr: string | Document) { - const doc = typeof xmlstr === 'string' ? parseXML(xmlstr) : xmlstr; + const doc = typeof xmlstr === "string" ? parseXML(xmlstr) : xmlstr; const templates = doc.getElementsByTagName("templates")[0]; if (!templates) { return; diff --git a/src/router/Router.ts b/src/router/Router.ts index c81866b9..c3b0425c 100644 --- a/src/router/Router.ts +++ b/src/router/Router.ts @@ -2,6 +2,7 @@ import { Env } from "../component/component"; import { QWeb } from "../qweb/index"; import { makeDirective } from "./directive"; import { LINK_TEMPLATE, LINK_TEMPLATE_NAME } from "./Link"; +import { shallowEqual } from "../utils"; type NavigationGuard = (info: { env: Env; @@ -111,6 +112,7 @@ export class Router { async navigate(to: Destination): Promise { const path = this.destToPath(to); const initialName = this.currentRouteName; + const initialParams = this.currentParams; const result = await this.matchAndApplyRules(path); if (result.type === "match") { const finalPath = this.routeToPath(result.route, result.params); @@ -121,7 +123,9 @@ export class Router { this.currentRoute = null; this.currentParams = null; } - if (this.currentRouteName !== initialName) { + const didChange = + this.currentRouteName !== initialName || !shallowEqual(this.currentParams, initialParams); + if (didChange) { this.env.qweb.forceUpdate(); return true; } diff --git a/src/router/directive.ts b/src/router/directive.ts index 65a23ed6..3ae2ee9c 100644 --- a/src/router/directive.ts +++ b/src/router/directive.ts @@ -13,7 +13,10 @@ export function makeDirective(env: RouterEnv) { // make new t t-component element const comp = node.ownerDocument.createElement("t"); comp.setAttribute("t-component", "__component__" + route.name); - comp.setAttribute(first ? "t-if" : "t-elif", `env.router.currentRouteName === '${route.name}'`); + comp.setAttribute( + first ? "t-if" : "t-elif", + `env.router.currentRouteName === '${route.name}'` + ); first = false; for (let param of route.params) { comp.setAttribute(param, `env.router.currentParams.${param}`); diff --git a/src/utils.ts b/src/utils.ts index e5d33a8b..e00e1326 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -95,3 +95,12 @@ export function debounce(func: Function, wait: number, immediate?: boolean): Fun } }; } + +export function shallowEqual(p1, p2): boolean { +for (let k in p1) { + if (p1[k] !== p2[k]) { + return false; + } +} +return true; +} diff --git a/tests/router/router.test.ts b/tests/router/router.test.ts index 8850bf74..fac78e06 100644 --- a/tests/router/router.test.ts +++ b/tests/router/router.test.ts @@ -25,6 +25,18 @@ describe("router miscellaneous", () => { ]); }).toThrow(`Invalid destination: {"abc":"hey"}`); }); + + test("navigate to same route but with different params should trigger update", async () => { + router = new TestRouter(env, [{ name: "users", path: "/users/{{id}}" }]); + env.qweb.forceUpdate = jest.fn(); + await router.navigate({ to: "users", params: { id: 3 } }); + expect(window.location.pathname).toBe("/users/3"); + expect(env.qweb.forceUpdate).toHaveBeenCalledTimes(1); + + await router.navigate({ to: "users", params: { id: 5 } }); + expect(window.location.pathname).toBe("/users/5"); + expect(env.qweb.forceUpdate).toHaveBeenCalledTimes(2); + }); }); describe("routeToPath", () => {