I'm trying to make a SPA (single page app) with Mithril.js. So far I've found very good tutorial here, and of course on Mithril homepage, but still cannot achieve combination of those two.
Here is modified working example from Dave's guide...
function btn(name, route){
var click = function(){ m.route(route); };
return m( "button", {onclick: click}, name );
}
function Page(content){
this.view = function(){
return [
m("page",
m("span", Menu.menu())
)
, m("div", content)
];
}
}
var Menu = {
menu: function(){
return [
btn("Home", "/home")
, btn("About", "/about")
];
}
};
var page_Home = new Page("The home of the Hobbits. Full of forests and marshes.");
var page_About = new Page(["The blighted home of Sauron. Scenic points of interest include:"]);
m.route(document.body, "/home", {
"/home": page_Home,
"/about": page_About
});
My JSON file:
[
{
"id":1,
"title": "Home",
"url": "/home",
"content":"This is home page"
},{
"id":2,
"title": "About",
"url": "/about",
"content":"This is about page"
},{
"id":3,
"title": "Galery",
"url": "/galery",
"content":"This is gallery page"
}
]
And my effort in combining those two from above:
//model
var PageSource = {
list: function() {
return m.request({method: "GET", url: "pages.json"});
}
};
var pages = PageSource.list();
var App = {
//controller
controller: function() {
return {
menu: pages
, rotate: function() { pages().push(pages().shift()); }
, id: m.route.param(pages.url)
}
},
//view
view: function(ctrl) {
return [
m("header"
, m("h1", "Page Title")
, m("span",
ctrl.menu().map(function(item) {
var click = function(){
console.log (item.url);
m.route(item.url);
};
return [
m("button", {onclick: click}, item.title)
];
})
)
, m("hr")
)
, m("button", {onclick: ctrl.rotate}, "Rotate links" )
, m("p", ctrl.content ) //CONTENT
];
}
};
//initialize
m.route(document.body, "/home", {
"/:id": App
});
And finally, questions are: - "How can I retrieve data from JSON file and display it in div based on selected button (routing)?" - "When I use m.route my entire view refreshes, but I only want to reload changed div. How?" Please help, 'cause so far I really like mithril.js
Thanks to @dcochran I've managed to achieve this:
//model
var PageSource = {
list: function() {
return m.request({method: "GET", url: "pages.json"});
}
};
var pages = PageSource.list();
var id = m.prop()
, url = m.prop()
, title = m.prop()
, content = m.prop();
var App = {
//controller
controller: function() {
return {
menu: pages
, rotate: function() { pages().push(pages().shift()); }
}
},
//view
view: function(ctrl) {
return [
m("header"
, m("h1", "Page title")
, m("span",
ctrl.menu().map(function(item) {
return [ btn(item.title, item.url) ];
function btn(name, route){
var isCurrent = (url === route);
var click = function(){
//m.route(route);
id = item.id;
url = item.url;
content = item.content;
title = item.title;
};
return m(
"button"+(isCurrent ? ".active" : ""),
{onclick: click},
name
);
}
})
)
, m("hr")
)
, m("button", {onclick: ctrl.rotate}, "Rotate links" )
, m(".page", content )
];
}
};
//initialize
m.route.mode = "hash";
m.route(document.body, "/home", {
"/:url": App
})