Hot controls initialize muliple times
Closed this issue · 1 comments
Hello.
octobercms@main from npm
This issue is not related to #29
Hot controls initialize muliple times, because the container.loadDefinition method first unloads the module and then loads it again
https://github.com/octobercms/ajax/blob/main/src/observe/container.js#L35C5-L35C19
But documentation says:
This function is idempotent, so calling it multiple times will take the first seen definition.
Example:
title = "Playground"
url = "/playground/:slug?"
==
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="turbo-cache-control" content="no-cache" />
<title>Playground</title>
</head>
<body>
<div data-control="playground">
<a class="btn btn-primary"
href="{{ 'playground'|page({
slug: ''
}) }}"
role="button">
Main page
</a>
{% set slug = this.param.slug|number_format + 1 %}
<a class="btn btn-primary"
href="{{ 'playground'|page({
slug: slug
}) }}"
role="button">
Page "{{ slug }}"
</a>
</div>
<script>
window.pageId = "{{ this.param.slug|default('main') }}";
</script>
<script src="{{ url(mix('js/playground.js')) }}" data-turbo-eval="false"></script>
{% if this.param.slug %}
<script src="{{ url(mix('js/playground-page.js')) }}" data-turbo-eval-once="{{ this.param.slug }}-page"></script>
{% else %}
<script src="{{ url(mix('js/playground-index.js')) }}" data-turbo-eval-once="index-page"></script>
{% endif %}
</body>
</html>
js/playground.js
// This is a common file that is used by all pages of the website and is loaded only once.
require("octobercms/src/framework-bundle");
js/playground-index.js
// here we load a common module that can be used on several pages (but not all at once)
import playground from "./playground/module";
playground(window.pageId);
// below is the code specific to this page
// ...
js/playground-page.js (in this example the files are the same, just to show how it works)
// here we load a common module that can be used on several pages (but not all at once)
import playground from "./playground/module";
playground(window.pageId);
// below is the code specific to this page
// ...
js/playground/module.js
export default function (pageId) {
oc.registerControl(
"playground",
class extends oc.ControlBase {
init() {}
connect() {
console.log(`CONNECT: ${pageId}`);
}
disconnect() {
console.log(`DISCONNECT: ${pageId}`);
}
}
);
}
When loading new pages, the previous script will be triggered first, then the new one
As a workaround i was added logic into "shouldLoad" method
export default function (pageId) {
oc.registerControl(
"playground",
class extends oc.ControlBase {
static get shouldLoad() {
try {
return !oc.importControl("playground");
} catch (error) {}
return true;
}
...
This function is idempotent, so calling it multiple times will take the first seen definition.
This statement appears to be false. It should be
This function can be called multiple times, and calling it multiple times will take the last seen definition.
The docs have been updated here:
octobercms/docs@8541e2b