Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multiple components sharing and reacting to global state #1934

Closed
kokujin opened this issue Aug 13, 2017 · 4 comments
Closed

Multiple components sharing and reacting to global state #1934

kokujin opened this issue Aug 13, 2017 · 4 comments

Comments

@kokujin
Copy link

kokujin commented Aug 13, 2017

Can someone point me to an example of several components sharing and reacting to global state? Thanks

@spacejack
Copy link
Contributor

spacejack commented Aug 13, 2017

@kokujin here's a really basic gist:

// appstate.js
import stream from 'mithril/stream'
// Assume we start with some default state (but don't have to)
const appstate = stream({movie: 'No movie loaded'})
export default appstate
// Redraw whenever changed.
// This may not be necessary if you're updating appstate in mithril event handlers or
// using m.request to fetch new data because those will trigger redraws automatically.
appstate.map(() => {m.redraw()})
// ... Later a different movie is loaded somehow ...
appstate({movie: 'Jaws'})

// ----

// comp1.js
import m from 'mithril'
import appstate from './appstate'
export default {
    view() {
        return m('h1', appstate().movie)
    }
}

// ----

// comp2.js
import m from 'mithril'
import appstate from './appstate'
export default {
    view() {
        return m('h1', appstate().movie)
    }
}

// etc.

@kokujin
Copy link
Author

kokujin commented Aug 14, 2017

Thanks @spacejack. I am still having problems, please bear with me.
I have tried your code on a button as an experiment. I would later like to update the contents of an accordion after an AJAX call.

I am defining and rendering a button as follows:

var btn = m("button", {class: "button"}, appstate().title); // <--- does not change
m.render('#container', btn); 

I am setting the value of appstate with the value I get back from my AJAX call, but the value of the button, "btn" does not change. I thought Mithril-stream creates something comparable to and observable?

@orbitbot
Copy link
Member

If you're using m.render, note that this method is relatively low-level and does not hook into the autoredrawing system that mithril provides: https://mithril.js.org/render.html#differences-from-other-api-methods -- you might want to use m.mount or m.route instead. If model changes are stored, m.render should update the DOM accordingly, however.

Otherwise, it's a bit difficult to tell what's going on specifically without seeing code.

@barneycarroll
Copy link
Member

@kokujin I hope you managed to solve your issue. One of the problems with the code you posted last is that it saves a reference to a vnode: vnodes should generally be created from scratch on every render in Mithril, otherwise it will assume nothing needs to change in the subtree.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants