Trying to get the hang of Mithril, can't really understand one thing. Can I render components on events?
Let's assume I have one parent component:
var MyApp = {
view: function() {
return m("div", [
m.component(MyApp.header, {}),
m("div", {id: "menu-container"})
])
}
};
m.mount(document.body, megogo.main);
It renders the header component (and a placeholder for the menu (do I even need it?)):
MyApp.header = {
view: function() {
return m("div", {
id: 'app-header'
}, [
m('a', {
href: '#',
id: 'menu-button',
onclick: function(){
// this part is just for reference
m.component(MyApp.menu, {})
}
}, 'Menu')
])
}
}
When the user clicks on the menu link I want to load the menu items from my API and only then render the menu.
MyApp.menu = {
controller: function() {
var categories = m.request({method: "GET", url: "https://api.site.com/?params"});
return {categories: categories};
},
view: function(ctrl) {
return m("div", ctrl.categories().data.items.map(function(item) {
return m("a", {
href: "#",
class: 'link-button',
onkeydown: MyApp.menu.keydown
}, item.title)
}));
},
keydown: function(e){
e.preventDefault();
var code = e.keyCode || e.which;
switch(code){
// ...
}
}
};
This part will obviously not work
onclick: function(){
// this part is just for reference
m.component(MyApp.menu, {})
}
So, the question is what is the correct way render components on event?
Try This: http://jsbin.com/nilesi/3/edit?js,output
You can even toggle the menu.
And remember that you get a promise wrapped in an m.prop from the call to m.request. You'll need to check that it has returned before the menu button can be clicked.
// I'd stick this in a view-model
var showMenu = m.prop(false)
var MyApp = {
view: function(ctrl) {
return m("div", [
m.component(MyApp.header, {}),
showMenu() ? m.component(MyApp.menu) : ''
])
}
};
MyApp.header = {
view: function() {
return m("div", {
id: 'app-header'
}, [
m('a', {
href: '#',
id: 'menu-button',
onclick: function(){
showMenu(!showMenu())
}
}, 'Menu')
])
}
}
MyApp.menu = {
controller: function() {
//var categories = m.request({method: "GET", url: "https://api.site.com/?params"});
var categories = m.prop([{title: 'good'}, {title: 'bad'}, {title: 'ugly'}])
return {categories: categories};
},
view: function(ctrl) {
return m("div.menu", ctrl.categories().map(function(item) {
return m("a", {
href: "#",
class: 'link-button',
onkeydown: MyApp.menu.keydown
}, item.title)
}));
},
keydown: function(e){
e.preventDefault();
var code = e.keyCode || e.which;
switch(code){
// ...
}
}
};
m.mount(document.body, MyApp);