Mounting class declarations
knynkwl opened this issue ยท comments
Hello, I love your library but I am having trouble getting some thing working.
I am using Barba.js as the PJAX library and ideally I would like to import modules that are on the page, call the init()
method and on pageLeave
call the detroy()
method on the module.
Here is what I have so far:
// This is loaded by Barba.js
export class Components {
constructor() {
conditioner.addPlugin({
moduleSetName: name => `./${name}/index.js`,
moduleGetConstructor: module => module.default,
moduleImport: name => import(/* webpackMode: "lazy" */ `${name}`)
});
}
onPageEnter(DOM) {
// lets go!
this.hydrate = conditioner.hydrate(DOM);
}
onPageLeave() {
// Need to destroy the loaded components, unless the are on the new page, in which case I need to reinit them with the new el
}
}
Is there a way to call a Class because when I do it gives me an error saying I can't call it as a function?
export default ExampleModule {
constructor() { }
init(slider) {
// Init Slider
}
destroy() {
// Destroy Slider
}
}
Some help on this would be amazing!!
This is the default set up.
export default (slider) => {
// Init Slider
return () => {
// Destroy slider
}
}
You could do this:
class ExampleModule {
constructor() {
this.init();
}
init(slider) {
// Init Slider
}
destroy() {
// Destroy Slider
}
}
export default (slider) => {
// Init Slider
const _myModule = new ExampleModule();
return () => {
// Destroy slider
_myModule.destroy();
}
}
Or override the moduleGetConstructor
and moduleGetDestructor
hooks.
@rikschennink Thanks for that.
How would I call the destroy()
/ init()
method on pageleave/enter? I don't see any example of that in the docs.
The hydrate
method returns an array of modules. You can call destroy
on each module when the page is unloaded.
Sorry for the back and forth, and I appreciate you helping me out with this!
on init I do:
init(){
this.hydrate = conditioner.hydrate(DOM);
}
then on destroy, this.hydrate returns an array of modules. do I have to loop over them all and call the destroy method for each?
Is there a way to check if these module are on the new page, without using the hydrate method again? I'm trying not to reimport the JS just reuse the module.
destroy() {
console.log(this.hydrate);
// returns [{module}, {module}, {module}]
this.hydrate.forEach(module => {
module.destroy()
});
}
in the case above, the module.destroy()
doesn't do anything
The destroy method returns an empty function. Where do I set that?
ฦ () {}
Should use unmount
instead => https://codepen.io/rikschennink/pen/bzzbJN?editors=1010
I'll look into this when I have some time
Okay thanks for the help.
Could you point me in the right direction with overriding the moduleGetConstructor
and moduleGetDestructor
hooks to accept a Class
module?
Would love to not have to have to call this at the bottom of each module:
export default (element) => {
const _myModule = new Slider();
_myModule.init(element);
return () => {
_myModule.destroy(element)
}
}
I think something like this, you'd have to set some debug statements to be sure.
conditioner.addPlugin({
moduleGetConstructor: module => {
return new module.default();
},
moduleGetDestructor: instance => {
instance.destroy();
}
});
module
returns undefined
in moduleGetConstructor
for some reason.
This is the class:
class ExampleModule {
constructor() {}
init() {}
destroy() {}
}
export default ExampleModule;
It took a couple tries but I got a working example: https://codepen.io/rikschennink/pen/wNOvJB?editors=1010
Nice, I had to update moduleGetConstructor
to include .default(element)
to get it working.
thanks for the help! I think it's working now
moduleGetConstructor: (module) => {
return (element) => {
return new module.default(element);
};
}
Fantastic! :) If you want you can close the issue
Sorry I'm late to the party.
I wanted to share how I've been handling a similar situation with a "pjax" library of my own.
I have all my modules in a modules
folder. There is an index.js
file that configures conditioner
and exports a hydrate
and an unmount
function that I call on every page transition. I looks a bit like this:
import * as conditioner from 'conditioner-core'
let boundModules = []
// Webpack
conditioner.addPlugin({
moduleSetName: name => name,
moduleGetConstructor: module => module.default,
moduleImport: name => import(`./${name}`)
})
// other plugins here, removed for brevity
export function hydrate () {
boundModules = conditioner.hydrate(document.documentElement)
}
export function unmount () {
boundModules.forEach(x => x.unmount())
}
Thank you @rikschennink for such an amazing library.