mirror of
https://github.com/discourse/discourse.git
synced 2025-02-23 04:55:00 +00:00
DEV: Ensure RenderGlimmer handles in-place component changes (#17946)
If a widget toggles between displaying two different RenderGlimmer instances, the Widget framework treats them as the same, and so `update()` is called rather than destroy/init. This commit detects this scenario and manually destroys/inits to ensure the correct component is being rendered.
This commit is contained in:
parent
1434fe3021
commit
3e010bc88c
@ -70,6 +70,16 @@ export default class RenderGlimmer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
update(prev) {
|
update(prev) {
|
||||||
|
if (
|
||||||
|
prev.template.__id !== this.template.__id ||
|
||||||
|
prev.tagName !== this.tagName
|
||||||
|
) {
|
||||||
|
// Totally different component, but the widget framework guessed it was the
|
||||||
|
// same widget. Destroy old component and re-init the new one.
|
||||||
|
prev.destroy();
|
||||||
|
return this.init();
|
||||||
|
}
|
||||||
|
|
||||||
this._componentInfo = prev._componentInfo;
|
this._componentInfo = prev._componentInfo;
|
||||||
if (prev.data !== this.data) {
|
if (prev.data !== this.data) {
|
||||||
this._componentInfo.data = this.data;
|
this._componentInfo.data = this.data;
|
||||||
|
@ -66,6 +66,41 @@ class DemoComponent extends ClassicComponent {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class ToggleDemoWidget extends Widget {
|
||||||
|
static actionTriggered = false;
|
||||||
|
tagName = "div.my-widget";
|
||||||
|
|
||||||
|
buildKey() {
|
||||||
|
return "abc";
|
||||||
|
}
|
||||||
|
|
||||||
|
defaultState() {
|
||||||
|
return {
|
||||||
|
showOne: true,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
html(attrs, state) {
|
||||||
|
const output = [
|
||||||
|
this.attach("button", {
|
||||||
|
label: "toggle",
|
||||||
|
className: "toggleButton",
|
||||||
|
action: "toggleComponent",
|
||||||
|
}),
|
||||||
|
];
|
||||||
|
if (state.showOne) {
|
||||||
|
output.push(new RenderGlimmer(this, "div.glimmer-wrapper", hbs`One`, {}));
|
||||||
|
} else {
|
||||||
|
output.push(new RenderGlimmer(this, "div.glimmer-wrapper", hbs`Two`, {}));
|
||||||
|
}
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
toggleComponent() {
|
||||||
|
this.state.showOne = !this.state.showOne;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
module("Integration | Component | Widget | render-glimmer", function (hooks) {
|
module("Integration | Component | Widget | render-glimmer", function (hooks) {
|
||||||
setupRenderingTest(hooks);
|
setupRenderingTest(hooks);
|
||||||
|
|
||||||
@ -73,11 +108,13 @@ module("Integration | Component | Widget | render-glimmer", function (hooks) {
|
|||||||
DemoComponent.eventLog = [];
|
DemoComponent.eventLog = [];
|
||||||
DemoWidget.actionTriggered = false;
|
DemoWidget.actionTriggered = false;
|
||||||
this.registry.register("widget:demo-widget", DemoWidget);
|
this.registry.register("widget:demo-widget", DemoWidget);
|
||||||
|
this.registry.register("widget:toggle-demo-widget", ToggleDemoWidget);
|
||||||
this.registry.register("component:demo-component", DemoComponent);
|
this.registry.register("component:demo-component", DemoComponent);
|
||||||
});
|
});
|
||||||
|
|
||||||
hooks.afterEach(function () {
|
hooks.afterEach(function () {
|
||||||
this.registry.unregister("widget:demo-widget");
|
this.registry.unregister("widget:demo-widget");
|
||||||
|
this.registry.unregister("widget:toggle-demo-widget");
|
||||||
this.registry.unregister("component:demo-component");
|
this.registry.unregister("component:demo-component");
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -217,4 +254,13 @@ module("Integration | Component | Widget | render-glimmer", function (hooks) {
|
|||||||
new RenderGlimmer(this, "div", hbs`<TheCorrectCompiler />`);
|
new RenderGlimmer(this, "div", hbs`<TheCorrectCompiler />`);
|
||||||
assert.true(true, "it doesn't raise an error for correct params");
|
assert.true(true, "it doesn't raise an error for correct params");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test("multiple adjacent components", async function (assert) {
|
||||||
|
await render(hbs`<MountWidget @widget="toggle-demo-widget" />`);
|
||||||
|
assert.strictEqual(query("div.glimmer-wrapper").innerText, "One");
|
||||||
|
await click(".toggleButton");
|
||||||
|
assert.strictEqual(query("div.glimmer-wrapper").innerText, "Two");
|
||||||
|
await click(".toggleButton");
|
||||||
|
assert.strictEqual(query("div.glimmer-wrapper").innerText, "One");
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
Loading…
x
Reference in New Issue
Block a user