Friday, July 10, 2009

Javascript MVC


När man jobbat mycket med Javascript så är det lätt hänt att man tappar lite av den kontroll man gärna vill ha i ett projekt. Så därför håller jag på att utveckla en MVC-modell för våra projekt, baserat på prototype.js. So far, efter knappt 600 rader kod, verkar det lovande, jag har försökt att efterlikna sättet Zend Frameworks API, då det onekligen är ett rätt genomtänkt API.

Ett snabbt exempel på hur det kan se ut:

// Script-delar:
...
// Modell för favoriter:
var FNLModel_Favorites = Class.create(FNLModel,{
   init:function($super, params){
      this.primary_key='user_product_id';
      $super(params);
   }
});   
...
// Javascriptdelen av view för favoriter
var FNLView_SingleSmallFavorite = Class.create(FNLView_Simple,{
   init:function(params){
      this.template = 'TEMPLATE_SINGLE_FAVORITE';
   }   
});
// Javascriptdel av en view för en favoritlista
var FNLView_SmallFavoriteList = Class.create(FNLView_Simple,{
   init:function(params){
      this.template = 'TEMPLATE_SMALL_FAVORITE_LIST';      
   },
   render:function($super,self){
      var str = '';
      for(var i=0;i<self.favorites.length && i<15;i++){
         self.favorite = self.favorites[i];
         str += self.render('SingleSmallFavorite');
      }
      self.favoriteContent = str;
      return $super(self);      
   }
});
...
// Controller för favoriter
var FNLController_FavoriteListLeft = Class.create(FNLController,{
   init:function(params){
      var self = this;      
      this.target = params.target;
      var callback = this.callback.bind(this);
// Lyssna efter uppdateringar av favoriter via ajax
      this.fnlTools.addEventListener({id:'favorites',event:FNLToolsEvents.ajaxResponse,callbackFunction:callback});
// Och se till att favoriterna uppdateras vid serveranrop.
      this.fnlTools.registerAjaxListener(this,FNL_CLUB_LISTENER_URL, 'favorites','user_product_id',-1);
      this.id=fnlTools.newUID;
   },
   callback:function(event){
      this.view.favorites = event.model.data;
      this.view.fnl_id = this.id;         
      str = this.view.render('SmallFavoriteList');         
      $(this.target).innerHTML = str;   
            
// Uppdatera serveranroparen så att den bara kollar efter nya favoriter
      this.fnlTools.updateAjaxListener(FNL_CLUB_LISTENER_URL, 'favorites',event.model.max());            
   }
});

...

// init-kod
fnlTools = new FNLToolsClass();
var productListUpdater = fnlTools.getController('ProductList',{target:'productList3'});


samt html-element som fungerar som templates:
<div id='TEMPLATE_SMALL_FAVORITE_LIST' style='display:none'>
#favoriteContent#
</div>
<div id='TEMPLATE_SINGLE_FAVORITE' style='display:none'>
<a target="_blank" href="#favorite.p_url#"><img width="44" title="#favorite.name#" src="http://stat2.shoppinggatan.se/public/images#favorite.thumb_local_url#" style="border: 2px solid rgb(201, 205, 208);"/></a>
</div>



Och vad gör då detta exempel? Jo, ett element med favoritprodukter skapas, och hålls dessutom uppdaterad om nya favoriter läggs till, endera i samma dokument, eller från en annan instans (för samma användare). Givetvis hanterar den dessutom hur många element som helst med samma innehåll, alla hålls uppdaterade i vilket fall. Det är också mycket lätt att hålla koll på alla events som sker på samma sida.

Om man tex skulle skriva ett litet chatrum med den nuvarande modellen så tror jag att det skulle handla om ca 30 minuters arbete, från start till mål. Givetvis inte aktuellt, då jag inte känner någon som chattar längre, men jag tycker ändå att det visar på kodens styrka. Javascripts svaghet med bara visst stöd för klasser syns i koden, men med Prototypes klasshantering så blir det lite enklare att koda.

En fundering som jag har är om det ska vara en instanserad controller per element, eller en instanserad kontroller per aktivitetstyp.

Om du är intresserad av att veta mer om det här, så är det bara att höra av dig.

Sunday, July 5, 2009

Reinfeldt sågar Amazon EC2


Som en del i regeringens förberedelser för höstens IT-proposition har statsministern och samtliga statsråd utvärderat varsin webhost. För statsminister Fredrik Reinfeldt föll lotten på Amazon EC2.
”Jag blev glad när jag fick veta att jag skulle testa Amazon – som partiledare har Amazon länge varit en fantastisk källa för litteratur inom statsvetenskap, och molnet har det talats rätt mycket om i Rosenbads korridorer.”

Men glädjen var kortvarig: ”Amazon är en användarmässig katastrof. Dokumentationen är mycket bristfällig, och arbetet med att skapa en Amazon-instans som passar just regeringens behov tog på tok för lång tid. Jag antar att en riktig Linux-hacker skulle klara det väldigt bra, men för en glad amatör som jag själv har det varit en mardröm.”

Reinfeldts stora kärlek till Open Source och molnlösningar är annars en välkänd historia. ”Hemma kör vi inget annat än Ubuntu. Många kollegor säger att Linux inte kan mäta sig med Windows som skrivbordsoperativ, men med den senaste versionen av Gnome finns det inte längre några ursäkter – Linux borde vara det naturliga valet för alla datoranvändare.”

Inom regeringen går åsikterna dock isär. Sten Tolgfors sägs vara en inbiten Mac-entusiast medan Sven Otto Littorin vägrar köra något annat än Windows XP. Göran Hägglund är den udda fågeln med FreeBSD.
”FreeBSD passar KD utmärkt”, berättar Hägglund. ”Min datortekniker säger att den påminner väldigt mycket om partiet – värdekonservativ men ändå frihetsbejakande. Och liksom KD är operativsystemet något av en underdog.”