Mithril.js: Should two child components talk to ea

2019-05-21 06:06发布

问题:

I'm a bit stuck looking for the right way to do the following. I have a parent component with two child components (see simplified code below). I would like to know the proper way for ChildA, when its button is pressed, to 'invoke' ChildB. They should communicate through the parent, but should they communicate through their controllers? In that case the parent has to pass its controller to the controllers of the children.

Parent = {
  view: function () {
    m.component(ChildA);
    m.component(ChildB);
  }
}

ChildA = {
  view: function () {
    m('button')
  }
}

ChildB = {
  view: function () {
  }
}

回答1:

This is really just a question of the plain javascript style you prefer. Think of communication between JS objects and how you would handle that.

Generally, Mithril devs choose between Parent/Child communication and Pub/Sub. For Parent/Children, the controller is commonly where devs place their logic. m.component accepts multiple parameters in which you can pass references (data/state/logic) to child components. See the docs. There's no need to pass Parent controllers to children.

However, I prefer to create a view-model which lives outside of any one component. It's where I keep view state (ie. form data) and view logic (ie. events, UI related callbacks, and shared state between components). This way, when I inevitably change/add components, I will not have to rework the controller logic in each component.

Leo Horie, the author of Mithril, wrote an article in which he explains communication between a Parent and One Child, but this can effortlessly be applied to multiple children.

Pub/Sub is a common JS idiom. The Mithril wiki lists a few community contributions that handle this. Go to the wiki, open the page titled "All Topics" and do a normal page search for "pub". You'll discover a few options there. Depending on the complexity of your app, your next move might be to search for a Pub/Sub library through google.



回答2:

I guess when you press the button of ChildA, some model state will be updated? Then, if both childs share the same model, the redraw done by Mithril after each event will update ChildB automatically.

My suggestion is to pass the model to the child objects and let ChildA also be a controller for the button. Why not the parent? Parents should usually handle commands that apply to multiple child views (or itself), and a button click seems simple/coupled enough for ChildA to manage that itself. But it depends on the real complexity of the system, of course. Always the problem with a simple example, it does not describe reality. :)

Here's an example how I mean anyway: http://jsbin.com/sipahe/edit?js,output

(Sorry for the Coffeescript, but it's brief and conveys the meaning very well.)



标签: mithril.js