Steg 4 – implementation
Slutresultatet
Innan jag börjar att berätta om resan så kommer här två skärmdumpar ifrån slutresultatet:


Så blev det =) Fast du vill säkert testa själv.. eller hur?
Studsa hit
Om det blir ett fel ifrån backend så gjorde jag så att felet kunde “blöda igenom” och visas på en “blue screen of death” som kunde se ut så här:

Just denna funktionen tyckte jag blev riktigt bra och väldigt hjälpsam då jag gjorde liten miss nånstans och glömde ett semikolon till exempel. Annars så “fastnar” gärna ett sånt här meddelande och man behöver öppna firebug för att se vad det var som egentligen hände.
Resan
Jaa.. var ska jag börja? Det har varit en kurvig resa genom implementationen vilket beror på brister i JavascriptMVC som jag valde att jobba med. Vanligtvis skulle ha jag ha dumpat ramverket p.g.a såna här brister men denna gången så höll jag envist kvar och genomförde implementationen.
1. Anropa controllers!?
Hur ända in i tusan anropar man en controller då det inte är via vanliga URL’s? Enligt dokumentationen finns det två sätt som man kan göra detta:
//1. Create a new controller directly:
new Todos($('#todos'));
//2. Use jQuery function
$('#todos').todos();
Det första sättet fungerade…. nästan. Controllern skapades men det blev ett javascript-fel med att ett element inte kunde hittas. Så det andra sättet (även kallat short-hand) var det enda sätt som fungerade för mig.
2. Controller init/setup
Så här kan koden se ut för en controller:
jQuery.Controller.extend('MyScribbles.Controllers.Main',
/* @Static */
{
},
/* @Prototype */
{
}
Återigen enligt dokumentationen så i den statiska delen ska man kunna (bör?) ha en init-funktion som har hand om att skapa gemensamma inställningar o.s.v. Problemet var dock att då jag hade det där så slutade shorthand-funktionen (se punkt 1) att fungera vilket gjorde att jag inte kunde anropa controllern alls. Meeen enligt dokumentationen så ska det gå – var det “skit bakom spakarna” eller brister? fortsätt läsa..
3. Vyer
JavascriptMVC har ett inbyggt system för vyer och templates som stödjer flera olika språk. Det jag körde med kallas för EJS och kan se ut på detta sättet:
<div id="<%= divid %>" title="Confirm removal" style="display:none;">
<p>Are you sure you want to remove the group '<%= group %>'?</p>
</div>
Här kan man se att denna template lägger in två variabler som skickas till vyn (divid och group). Förutom det så är det vanlig HTML-kod givetvis. Man kan också använda javascript-funktioner i en vy så här:
<% for(var n=0; n<groups.length; n++) { %>
<!-- do something -->
<% } %>
Så när jag glad i hågen jobbade med vyer så fick jag problem när applikationen vägrade att ladda vyn som hette “form_setname.ejs”. Felmeddelandet var bara att filen kan inte hittas. Så jag spenderade cirka 4 (!) timmar med att felsöka detta – kontrollera filnamn, läsa dokumentation och kontrollera sökväg m.m. Till slut så hittade jag orsaken (INTE med hjälp av dokumentation!); en vy kan inte heta nånting med underscore därför att det finns inbyggda regler hur namngivning ska ske som tolkar det helt åt pipskogen.
Denna namngivningen är också sammankopplad med funktionsnamn.. Shorthand-funktionen “my_scribbles_main” blir så p.g.a dessa regler. Det egentliga namnet är MyScribbles.Controllers.Main. Med en hel del tänkande inser jag att namngivning med camelcase blir tydligen avdelat med underscore som “MyScribbles” blir “my_scribbles” vilket betyder att det måste tolkats som att “form_setname” så skulle filen ha hetat “formSetname”. När jag sedan tog bort underscore så fungerade det alldeles utmärkt.
Från design till implementation
Min ursprunliga skiss hur jag skulle implementera gjorde jag med några små ändringar:
- Ett nytt objekt som heter Scribble (prototype-baserad) för att kunna instansiera och sköta allting som har med en scribble att göra.
- Ett statiskt hjälpbibliotek till hela applikationen med funktioner för att t.ex visa ett ok/fel-meddelande.
- Implementerade biblioteket jQuery Window som sköter om en scribble med inbyggda funktioner för fönsterhantering helt enkelt.
Slutsats
Förutom dom tre problemen jag listade under resan så när jag skulle ladda upp projektet till mitt webhotell tänkte jag gå över ifrån development-läge till production. Vad tror ni händer då? SPLATT! Jahopp.. där dog applikationen – bara att fortsätta köra i development då.
Så jag är inte direkt imponerad utav JavascriptMVC p.g.a alla brister där den största är dokumentationen som är rörig och även delvis felaktig. Såna projekt bara SKA ha en riktigt bra dokumentation – punkt slut.
Jag tycker att hela JavascriptMVC-projektet är inte speciellt stabilt och överlag en känsla av; implementera MVC-modell i Javascript bara för att det går. Men jag blev bekant med en väldigt intressant del som jag inte kände till innan, nämligen vyer och templatesystem för Javascript. Så skulle jag göra en rekommendation så vore det att skriv på vanligt sätt med en smart uppbyggnad av objekt och använd sedan någon templatemotor. Jag såg att det finns ett flertal olika projekt och lösningar just för detta.
Först mot slutet av implementationen så kom jag in i ramverket och började känna mig bekväm samt förstod hur det fungerade. P.g.a det så kom jag aldrig in på de andra delar som finns i JavascriptMVC som automatiska tester. Jag vet sen innan att man måste kunna språket och miljön man jobbar med för att kunna skriva tester – annars tar det bara tio gånger längre tid där hälften är slöseri.
Källkod
Den aktuella källkoden som jag strippade på en del onödigt ligger under “trunk/deployment version 1.0″ – visa hos Google Code
Tags: buggar, implementation, Javascript, javascriptmvc
March 11th, 2011 at 8:46 am
Snyggt jobbat, herr Johansson!
Förstår att större delen av din restid gick åt till att tämja JavaScriptMVC. Vågar man hoppas på att du gör din fördjupning där? Vore kul att höra mer ingående om vad du tycker om ramverket, framför allt eftersom du verkar ha satt fingrarna på några pain points.
Vad gäller själva appen så är den ju riktigt söt.
Din blue screen of death blir man ju nästan nostalgisk av! (om någon annan tjyvläser detta och vill testa; välj “remove” och “new” i kombination)
Den är något begränsad i funktionalitet, men det som finns funkar väldigt väl. En sak jag saknar är att kunna dra en scribble mellan grupper, det är en sådan där sak som man genast intuitivt testar! Eller åtminstone att kunna ändra grupper via dropdown i edit-menyn för en Scribble. Men, det är ju inte funktionaliteten som ska stå i första rummet, så no worries.
Lyckas inte ändra bakgrundsfärg på en scribble? Kanske inte implementerat?
Bra integrering av jQuery UI, du har dragit nytta av dess bättre beståndsdelar. Drag&drop och dialoger funkar riktigt bra.
(parentesnotering till nästa steg: tillåt inte resizing av textfältet i en scribble!)
Vad gäller koden så är strukturen till stor del given av JavaScriptMVC, och du verkar ha följt mallen väl. Gillar framför allt hur vyerna isoleras, det är (enligt mig) den största fördelen med MVC, som annars kan kännas lite krystat emellanåt.
Ska jag hitta något att gnälla över (och det har jag ju betalt för) så skulle det möjligen vara att din main_controller.js känns ganska bloated och generell. Kan man inte isolera en del av dess spridda funktionalitet på annat håll?
Det känns också som du missbrukar Model-konceptet när det gäller din implementation av Group. Här har du bara instansmetoder, men de fungerar i själva verket som statiska metoder (ingen hänvisning till this). Så istället för att instansiera Group i main controller hade du kunnat använda koden som en singleton. Precis som du gör för Scribble; här använder du bara statiska metoder. I Scribble känns det dessutom nästan tvärtom emellanåt; dina CRUD-metoder där skulle kunna varit instansmetoder istället. Men, det spelar mindre roll.
Överlag: good work! Du har läst in dig på ett antal nya teknologier, och blandat ihop dem till en fungerande app som ganska väl följer din designplan!
March 15th, 2011 at 12:20 am
Det låter som om du använder Chrome som webbläsare kanske? Att textfältet är resizable är inget medvetet gjort – vet att Chrome iaf har detta inbyggt. Vet inte om man kan blockera det?
Applikationen är främst testad i Firefox även om jag testat sporadiskt i bl.a Chrome.
Att main_controller är lite bloated.. ja, delvis. Jag hade prolem med funktionen showCrash som ligger dubbel på några ställen bara därför att det inte fungerade att anropa en funktion i controllern – bugg i JavascriptMVC. Det sätt som det står i dokumentionen fungerar inte.
Min tanke och plan ifrån början var att samtliga modeller skulle instansieras istället för slutresultatet; att en statisk och en som instansieras. Det blev så delvis p.g.a tidsbrist och problemet jag skrev ovan att anropa funktioner i en controller.
Det finns en del man kan göra refactoring på som att flytta ut mer i hjälp-klassen och kanske skriva om modellerna till en generell klass eftersom bägge två funkar i tre lägen med olika parametrar (url, post/get samt json-svar eller text-svar).