What is the correct way to update a child element based on parent?
var parentModel = {
childId: 1
}
var parent = {
view: function(vnode) {
return [
m("h1", "Editor " + parentModel.childId),
m("button", {onclick: function(){parentModel.childId++}}, "Next"),
m(child, parentModel)
]
}
}
/////////////////////////
var childModel = {
id: 0
}
var child = {
oninit: function(vnode) {
childModel.id = vnode.attrs.childId
},
view: function(vnode) {
return m("h2", "Editing " + childModel.id)
}
}
m.mount(document.body, parent)
https://jsfiddle.net/volnei/8L123yxt/
Child element updated
Child element is not updated
You must also sync the models from the onbeforeupdate hook: https://jsfiddle.net/8L123yxt/4/
Since I working with a master/detail, can you say if this is the best way in terms of architecture?
This is an anti pattern whereby you want to read directly from the attrs in the view, but instead you're assigning the value of a particular attribute to state in oninit and then referring to that cached value.
If you remove the oninit and simply reference the desired attribute in the view, you'll be fine:
var child = {
view: function(vnode) {
return m("h2", "Editing " + vnode.attrs.childId )
}
}
Without knowing what the intent of the childModel object is, I'd recommend keeping it simple and avoid the indirection of assigning the value to an intermediary object in one place only to retrieve it later — in the absence of other requirements it just looks like an opportunity for bugs to arise — but if for some reason you really need to update an external model, you can make your code work by taking that same function currently bound to oninit and also binding it to onbeforeupdate
I don't agree that it's an anti-pattern, per se, (@barneycarroll), but generally, you want to avoid persistent state where practical. Not only would that solve your problem here, but it's also helpful in general to avoid bugs and keep things more testable (stateless rendering is easy to test).
Most helpful comment
This is an anti pattern whereby you want to read directly from the attrs in the view, but instead you're assigning the value of a particular attribute to state in oninit and then referring to that cached value.
If you remove the oninit and simply reference the desired attribute in the view, you'll be fine:
Without knowing what the intent of the
childModelobject is, I'd recommend keeping it simple and avoid the indirection of assigning the value to an intermediary object in one place only to retrieve it later — in the absence of other requirements it just looks like an opportunity for bugs to arise — but if for some reason you really need to update an external model, you can make your code work by taking that same function currently bound tooninitand also binding it toonbeforeupdate