I'm using Halogen to control a menu system for my application, and I'm wondering how I can "destroy" a Halogen component. Right now, I have a function that creates a submenu component on a div with a particular ID. Throughout the lifecycle of the app, the submenu could be visited multiple times, so currently multiple instances of the component are created whenever the visitSubMenu
function is called.
import Halogen.Aff as HA
import Halogen.VDom.Driver (runUI)
visitSubMenu = do
elem <- HA.selectElement "#submenu"
case elem of
(Just element) -> do
liftEff $ HA.runHalogenAff do
io <- runUI subMenuComponent unit element
-- other code using component io...
Ideally, I'd like the submenu component to be removed when the user is done with their work in the submenu (i.e. the HTML injected into #submenu is removed, other cleanup happens). Is that sort of thing possible? I realize I could setup the component only one time at the start of the app, and keep it alive throughout the life of the app, but it seems better to me if I only set it up when it's needed.
I doubt this is the right way to do it, but my initial thought is I could create a lifecycleComponent, and when I want to destroy it, I can send a Finalize
query and then manually remove the parent element from the DOM.
In the end, the only solution I found was to send a "Cleanup" query to the component, and then remove the root DOM element of the halogen component.
FFI
exports.removeElementById = function(id) {
return function() {
var e = document.getElementById(id);
if (e) e.remove();
}
}
Halogen Component Module
foreign import removeElementById :: String -> Eff (dom :: DOM | e) Unit
removeSelf :: forall e. Aff (dom :: DOM | e) Unit
removeSelf = liftEff $ removeElementById componentId
componentId :: String
componentId = "unique-id-for-component"
render :: State -> H.ComponentHTML Query
render state = HH.div [HP.id_ componentId] []
So then I can call removeSelf
when I'm finished using the component.