En kalender med mithril components
Vi har i kursmoment 1 och 2 tittat på modeller och vyer i mithril. Ofta vill man kunna återanvända komponenter för att förenkla
utvecklingen av komplexa vyer. Mithril har ett inbyggd sätt att skapa och återanvända komponenter i m
-funktionen. Dessa återanvändbara komponenter kallas helt enkelt Components och i denna övningen skall vi titta närmre på dessa.
#Introduktion
Vi kommer i denna övning bygga en kalender med hjälp av mithril components och Svenska Dagar api’t. Källkoden för detta exempel finns i example/calendar
och på Github.
#En vy för vår kalendar
Det första vi gör är att skapa en vy där vår kalender kommer synas. I och med vi bara ska ha en vy för vår kalender använder vi funktionen m.mount
för att läsa in vyn från js/index.js
.
// js/index.js
"use strict";
var m = require("mithril");
var Calendar = require("./views/calendar");
var app = {
initialize: function() {
document.addEventListener('deviceready', this.onDeviceReady.bind(this), false);
},
onDeviceReady: function() {
m.mount(document.body, Calendar);
}
};
app.initialize();
Vi skapar sedan vyn js/views/calendar.js
, här importerar vi vår model, som kommer sköta kommunikationen med https://api.dryg.net
och hantering av svaret. Vi använder livscykel metoden oninit
för att hämta data från vår model. I vår view
funktion hämtar vi sedan ut de dagar som har hämtats från api’t och med hjälp av map
itererar vi igenom alla dagarna. Från map
anropar vi mithrils m
-funktion, men till skillnad från vad vi har gjort tidigare anropar vi det med ett objekt Day
istället för med en sträng, som talar om vilken virtuell nod vi vill skapa. Det objekt vi anropar är en mithril komponent. Objektet Day
har en enda funktion view
, som returnerar de virtuella noder som komponenten består av. Vi skickar med varje element från Calendar_model.days
array. Vi kommer åt attributen i elementen via vnode.attrs
, precis som vi sett tidigare i samband med länkar.
// js/views/calendar.js
"use strict";
var m = require("mithril");
var CalendarModel = require("../models/calendar");
var Day = {
view: function (vnode) {
return m("div.day" + vnode.attrs.red_day, [
m("p", [m("strong", vnode.attrs.date)]),
m("i", vnode.attrs.weekday)
]);
}
};
module.exports = {
oninit: function () {
CalendarModel.load();
},
view: function() {
return [
m("h1", "Calendar"),
m("div", CalendarModel.days.map(function (day) {
return m(Day, day);
}))
];
}
};
Nedan finns koden för vår Calendar
model, som hämtar och behandlar data från api.dryg.net
. Modellen hämtar ut dagarna för nuvarande månad. Jag har vald att lägga databehandlingen i modellen för att hålla vyn så enkel och kort som möjlig.
// js/models/calendar.js
"use strict";
var m = require("mithril");
function zero_pad (number) {
if (number < 10) {
number = "0" + number;
}
return number;
}
var Calendar = {
days : [],
load: function () {
var today = new Date();
var apiURL = "https://api.dryg.net/dagar/v2.1/" + today.getFullYear() + "/" + zero_pad(parseInt(today.getMonth()) + 1);
return m.request({
method: "GET",
url: apiURL
}).then(function (result) {
Calendar.days = result.dagar.map(function (dag) {
return { date : dag.datum, weekday : dag.veckodag, red_day : dag["röd dag"] === "Ja" ? ".red-day" : "" };
});
});
}
};
module.exports = Calendar;
Nedan syns den färdiga kalendern med en enkel styling. Röda dagar är markerade genom att använda red_day
attributet från våra dags element i arrayen.
#Avslutningsvis
Detta var ett enkelt exempel på hur man kan återanvända komponenter i mithril för att skapa en bra uppdelat kodstruktur. Genom att dela upp iterationen av dags element och renderingen av dagarna har vi skapat ett enkelt sätt att återanvända och ändra i koden för visningen och iterationen.
Hade du kunnat lägga till namnsdagar i kalendern? Eller lagt till en vy, som visar all information, vid klick på en av dagarna?
#Revision history
- 2017-03-13: (A, efo) Första utgåvan inför kursen webapp v2.