KnockoutJS – CRUD eksempel 1

Jeg har længe gerne ville skrive om et Javascript framework, som jeg benytter mig af. Det hedder nemlig KnockoutJS og det er i mine øjne et genialt værktøj at have i sit arsenal af programmerings frameworks. Jeg ved ikke helt om man kan sige at KnockoutJS er i kategori med AngularJS, så lad endelig være med at hænge mig op på det. Dog har jeg fundet ud af at jeg er blevet enormt glad for Knockout.

Hvad er KnockoutJS?

Knockout er et Javascript MVVM (Model-View-ViewModel) framework som hjælper dig med at skrive dynamiske UI’s, som du kan gøre stor gavn af. Jeg har f.eks lige lavet en lille test “plunker” som du kan se, her har jeg lavet et CRUD (Create, update and Delete) eksempel med Bootstrap v3 og Knockout. Det har ca taget under en time at skrive et nogenlunde overskueligt “CRUD” eksempel.

Ved hjælp af en nem skrevet Knockout ViewModel har du mulighed for at skrive et rigt og æstetisk interface, som opdaterer dynamisk mens dine brugere benytter sig af det. Uden at du har en masse logik i dit html view. Knockout benytter sig nemlig af data-bind attributten som du kan bruge til at binde et object op imod.

Hvordan kommer jeg igang med KnockoutJS?

Well, jeg vil anbefale dig at have meget god kendskab til HTML og CSS. Derudover er det også godt at have kendskab til Javascript og JQuery. Selvom KnockoutJS ikke er dependent på JQuery, så kan man få god udnyttelse af både KnockoutJS og Jquery.

KnockoutJS har også en fantastisk interaktiv tutorial (gad vide hvordan den er skrevet ;-) ) som du kan prøve kræfter med her.

Mit Knockout CRUD eksempel

Nu vil jeg ikke mene jeg er den bedste Javascript programmør, men jeg fik da på kort tid skrevet mit CRUD (create, update and delete) eksempel i Javascript frameworket KnockoutJS. Her vil jeg kort gå igennem hvordan jeg gjorde, og hvorfor jeg gjorde det på denne måde.

Jeg har skrevet en lille JS constructor fil, som har til formål at oprette nye objekter til mit knockout ViewModel. Her har jeg skrevet en constructor for et job objekt, som indeholder 4 ko.observable og en update function. update functionen tager imod et alm. javascript objekt og bruger det til at oprette job objektet med ko.observables.

Editable bruges til at definere om objektet er i redigerbar tilstand eller ej.

Først har vi 3 properties: Company, jobTitle og description som hver er en ko.observable(), hvilket fortæller knockout at dette er et property som skal trackes og hvis der sker ændringer. Så skal du informere UI’et om ændringen. Derefter fremvises den ændret værdi i UI’et. Jeg har også skrevet en extension (update) som går ind og opdaterer værdierne i objektet. Dog ved jeg ikke om det er den rigtige vej at gå endnu.

Min knockout ViewModel ser således ud:

I mit knockout ViewModel, der fortæller jeg knockout frameworket hvad i skal holde øje med og hvad jeg kan bruge til at binde i vores html. Her skriver jeg også diverse functioner som skal bruges til at have alle CRUD funktionaliterne, såsom opret, update og slet. Til allersidst, så fortæller jeg Knockout omkring mit view ved brugen af ko.applyBindings() funtionen. Men lad os tage fat i det, skridt for skridt.

Opret nyt arbejde

For at oprette et nyt job, har jeg brugt en observable newJob som kommer til at være et placeholder objekt. Når folk trykker på knappen “add new job” så tager vi fat i funktionen som hedder showform():

Ved hjælp af  Data-bind=”click: ShowForm” så fortæller vi KnockoutJS at når der klikkes på dennne knap, skal du bruge følgende funktion Showform. Showform funktionen oprettet et placeholder observable objekt kaldet newJob som indeholder et “tomt” job objekt og så snart newJob ikke er null, så viser vi opret formularen til oprettelse af et nyt jobm ved brug af data-bind=”with: newJob” i tabellen. i denne tr ses tre input felter som hver især benytter sig af KnockoutJS’ value binding, som binder værdien af den value der er i input feltet til dens observable der matcher.

Sidst ses 2 knapper der hver bindes til en funktion i vores KnockoutJS viewmodel, addNewJob og cancelNewJob. Det eneste cancelNewJob gør er at sætte værdien af newJob observable til null, derefter forsvinder formularen og alle input felterne bliver derefter nulstillet, da det tidligere job objekt er blevet erstattet med null.

I addNewJob benytter vi af os lidt mere ko og her kommer vi ind på ko.toJS som er en funktion der omdanner et Knockout object til et plain javascript object som vi derefter passer ind igennem vores update extension. På vores KnockoutJS observableArray tilføjer vi et ekstra objekt ved at benytte .unshift(), som tilføjer et objekt øverst til dit array. Der er langt flere funktioner man kan gøre brug af i ens array, og det kan du læse om på KnockoutJS’ hjemmeside.

Efter vi har tilføjet data til array’et så benytter jeg mig af lidt ToastrJS til at give en lille fin growl notification i hjørnet. Sidst men ikke mindst, tildeler jeg null til newJob observable og derefter forsvinder opret formularen. Simpelt ik? :-)

Foreach jobs

Som det næste i opgaven, så skal vi jo vise hvad vi har i vores observableArray, og det har jeg gjort ved at benytte mig af KnockoutJS’ smarte måde man kan lave såkaldte templates på. Her har jeg gjort brug af en comment med foreach metoden. Du kan også bruge data-bind=”foreach:  jobs” eller benytte dig af et rigtigt JS template.

Inde i mit template gør jeg brug af  visible: !editable(), her kalder jeg faktisk ind i objektets editable observable. Hvis editable er false, så vises det. Hvis derimod editable() er true, så vises det ikke, men derimod vises edit/update delen af templatet.

Der er en bedre måde at gøre dette på og det er ved at benytte sig af KnockoutJS’ custombinding, hvor du kan udvide funktionaliteten bag KnockoutJS – Det er ikke en last resort ting, men noget teamet bag KnockoutJS anbefaler man gør brug af. På denne måde kan vi undgå at have logik i vores html såsom visible: editable(), brugte jeg nu en custombinding, så kunne det se sådan ud: data-bind=”hidden: editable”, hvilket ser meget bedre ud. Det har jeg dog ikke gjort i denne omgang, og gemmes til en anden god blog ;-)

Slet et arbejde

Nu er vi nået dertil hvor vi igen kan kigge lidt nærmere på funktionaliteterne. Det der primært er tilbage er Edit/update, som jeg har været lidt inde på men også slet et abejde. Slet er heldigvis en relativ simpel opgave at løse. Vi har en knap i vores html der binder ved en click til deleteJob function, som består af følgende:

Når man trykker på knappen, så køres funktionen deleteJob hvor vi passer vores data (det objekt som tilhører klik funktionen), ved hjælp af remove(data) fjernes det pågældende objekt fra vores observableArray og dit UI opdateres. Wupti, vi har nu slettet et arbejde fra listen.

Update / Edit

Det jeg klart har syntes der har været svært ved KnockoutJS, har været at skabe en kanon god måde at lave et editor pattern. I min kommende applikation, der endte jeg med at mit første KnockoutJS viewModel var på over 400 linjer kode, og meget af det var noget rod (det eneste de her 400 linjer kode ku var CRUD funktioner), med observables her og der for at skrive et fungerende ViewModel. Men det var bestemt ikke særlig maintainable. Mit problem var helt basalt edit/update funktionaliteten som jeg ikke ku finde hoved og hale i, dog tror jeg at jeg har fundet en god løsning nu her.

Når du trykker på edit knappen i vores html, så benytter vi igen af vores click binding og fortæller at når der trykkes på edit skal du kalde funktionen editJob og pass objektet til funktionen. Hvis man fortryder sin redigering, så er det nødvendigt at der oprettes backup properties. Knapperne i UI’et ændrer sig også fra “Edit / Delete” til “Save / Cancel” ved hjælp af objektets editable().

Beslutter man sig for at ens ændringer er gode nok, så trykker man “Save” som derefter kalder en funktion jeg har valgt at kalde acceptJob, som essentielt blot ændre værdien af editable() til false. Da vi skriver direkte ind i objektets observable() ved hjælp af value bindingen, så objektet har allerede de indtastet data. Nemt ik?

Fortryder vi derimod vores redigering, så benytter vi os af Cancel knappen som kalder ind i vores cancelEdit

Her benyttes vores tidligere værdier som er blevet gemt i vores backup properties, vi ændre samtidig editable til false.

Vi har nu en editor pattern i KnockoutJS som er simpelt og virker. Men se endelig mit eksempel på Plunker, jeg håber min korte introduktion vil give dig blod på tanden til at forsøge dig med KnockoutJS.

One comment on “KnockoutJS – CRUD eksempel

  1. Reply Eik Emil Christensen jan 30,2014 11:29

    Jeg har kigget lidt igennem koderne og forsøgt at forbedre det en smule. Du kan se min opdateret version her: http://embed.plnkr.co/JkJRlA/preview

Skriv et svar