Auch KnockoutJS bietet mithilfe von CustomBindings und Components die Möglichkeit die HTML-Syntax für seine Anwendung aufzubohren und wartbarer zu gestalten. Dies habe ich allerdings im Folgenden nicht weiter verfolgt und verweise hier auf die Dokumentation: http://knockoutjs.com/documentation/component-overview.html und http://knockoutjs.com/documentation/custom-bindings.html
Dies ist eigentlich alles an Konzepten, welche KnockoutJS mitbringt. Es ist viel weniger eigensinnig wie vergleichsweise EmberJS und AngularJS. Und das muss nicht unbedingt schlecht sein.
Für weitere Konzepte wie Routing oder Dependency Verwaltung verweist KnockoutJS auf andere kleine Bibliotheken wie Pager.js für das Routing oder Require.js für die Dependency-Verwaltung.
Das Ergebnis
Aber nun mal direkt zur Umsetzung der Konzertapplikation mittels KnockoutJS. Ich habe für die Umsetzung die Version 2.3.0 verwendet.
Die Sourcen liegen unter https://github.com/holgergp/concertKnockout und die Anwendung ist zu sehen unter http://concertknockout.herokuapp.com/
Ähnlich wie bei den anderen Ansätzen, wollte ich mir auch hier die Struktur der Anwendung mithilfe von yeoman generieren lassen. Hierfür habe ich den inoffiziellen Generator unter https://github.com/bmac/generator-knockout verwendet.
Dieser lief vergleichsweise prima und ohne nennenswerte Zwischenfälle. Erwähnenswert ist, dass dieser Generator das Projekt direkt mit der oben erwähnten Dependency-Management-Bibliothek require.js anlegt. Im Vergleich zum EmberJS-Generator verzichtet dieser allerdings darauf die Sourcen zu compilieren/minfizieren. Für den Einstieg und für die Übersicht sehr schön.
Auf ein “richtiges” Modell habe ich hier verzichtet und habe mich auf ein ViewModel beschränkt.
Hierfür habe ich pro Konzertart eine Funktion vorgesehen. Die jeweiligen Konzerte werden als “obervableArray” hinterlegt, wobei ich Testdaten jeweils hart vorgefüllt habe.
Die “ViewLogik”-Formatierung des Datums und Kennzeichnen der Fälligkeit eines Konzerts habe ich als “computedProperty“ umgesetzt. Das klappte hier problemlos.
Für den jeweiligen Konzertbereich habe ich Knockout, wie in der Einleitung beschrieben über ko.applyBindings(loveConcertsViewModel, $('#loveConcertSection')[0])
; aktiviert (https://github.com/holgergp/concertKnockout/blob/master/app/main.js#L138)
Interessant ist noch der vierte Bereich, das Formular für die “NewConcerts”. Hier definiere ich ein neues Konzertelement, welches in die oben definierten Arrays verschoben wird. (https://github.com/holgergp/concertKnockout/blob/master/app/main.js#L152-L169)
Das Binding der einzelnen Properties habe ich über ko.observable(property)
; angewiesen.
Drag-and-drop war etwas tricky umzusetzen. Ich habe hierfür die nur knapp dokumentierte Bibliothek von one.com verwendet. Richtige Überraschungen sind aber auch hier nicht aufgetreten.
Das Template habe ich strukturell der Einfachheit halber von meiner AngularJS-Lösung übernommen, und das klappte auch recht gut. Es gilt hierfür Ähnliches wie für die AngularJS-Umsetzung: Wir haben, wie oben schon angedeutet, drei Bereiche für die Konzerte und einen für die neuen Konzerte. Die Drag-and-drop-Lösung ist ebenso wie im “Original” nicht selbstverständlich.
Etwas merkwürdig finde ich die kommentarartige Syntax für das Textbinding, das ist aber Geschmackssache (https://github.com/holgergp/concertKnockout/blob/master/index.html#L119-L122).
Auch der Service und Provider sind von meiner AngularJS Lösung “übriggeblieben”, diese sind kein Mittel von KnockoutJS. Ich fand diese nur ein ordentliches Mittel zur Strukturierung (https://github.com/holgergp/concertKnockout/blob/master/app/main.js#L186-L220).
Erwähnenswert fand ich noch die Dependency-Verwaltung per Require.js. Dies ist nicht ganz selbsterklärend, aber durchaus schön: Injektion hier: https://github.com/holgergp/concertKnockout/blob/master/app/main.js#L4 und die Konfiguration hier: https://github.com/holgergp/concertKnockout/blob/master/app/config.js
Für die Unit Tests wird die Verwendung von QUnit empfohlen. Die Kombination aus QUnit und require.js lief nicht Out-of-the-box, da das Laden der Abhängigkeiten ja komplett in requiere.js Hand ist. Dies war aber schlussendlich recht einfach ans Rennen zu bringen.
Insgesamt gefällt mir die Lösung mit KnockoutJS sehr gut, die Entwicklung fühlt sich recht zügig an. Allerdings muss man wissen, wo die Grenzen von KnockoutJS sind, beispielsweise greift man bereits für FormValidation auf Plugins oder jQuery Mittel zurück. Das Abstraktionsniveau ist niedriger, dafür erscheint mir die Lösung recht klar. Man darf nicht außer Acht lassen, dass KnockoutJS “nur” eine Bibliothek ist.
Wenn Sie sich für ein Framework mit den Mitteln von KnockoutJS als Unterbau interessieren, könnte für Sie das Framework Durandal oder dessen Nachfolger Aurelia interessant sein.
KnockoutJS ist für mich ein guter Kandidat, wenn man wirklich nur diese kleine Schicht über jQuery in seinem Projekt benötigt oder vielleicht bestehenden jQuery Code strukturieren möchte und dafür kein schwergewichtiges Framework einsetzen möchte.
Fazit
Mein Fazit für KnockoutJS und die Konzertanwendung. Ich verwende hier wie gehabt die Skala + (gut), 0 (ok), – (nicht so gut):
Einarbeitung: +
- KnockoutJS ist recht übersichtlich.
- Einige Aspekte wie die ViewModels versteht man vielleicht nicht sofort.
- Das Tutorial auf http://learn.knockoutjs.com/ gefällt mir sehr gut.
Wartbarkeit: 0
- Da KnockoutJS wenig Vorgaben macht, hängt dies stark von Ihrem Projekt ab. Ich schätze aber, dass ein KnockoutJS-Projekt wartbarer sein kann, als ein reines jQuery-Projekt.
Lassen sich auch anspruchsvolle Anforderungen umsetzen: 0
- Ja, allerdings gibt es weniger Features out-of-the-box (z.B.: FormValidation).
- Drag-and-drop war etwas tricky, aber nicht viel schwieriger als bei den anderen Kandidaten.
Wie gut lässt sich die Anwendung testen? 0
- Hier gilt gleiches wie für EmberJS:
- Ja, eine KnockoutJS-Anwendung lässt sich gut testen, allerdings steht dieses nicht so im Vordergrund wie bei AngularJS.
Wie groß ist die Community? 0
- Auch hier gilt Ähnliches wie für EmberJS:
- Kleinere Community als bei AngularJS, aber ich habe auf alle Fragen gute Antworten gefunden
- Auf Stackoverflow gibt es zu Knockout.js ca. 14.000 Fragen (Stand 22.06.2015).
Wie gut ist die Dokumentation? +
- Die Dokumentation gefällt mir gut, muss allerdings auch weniger leisten, als bei den beiden anderen Kandidaten.
Am Ende
Vielen Dank, dass Sie es bis hierhin durchgehalten haben! Ich hoffe, Sie konnten ein wenig mitnehmen und hatten – wie auch ich – ein wenig Spaß dabei. Ich hatte mit allen drei Ansätzen Freude. Ich bin nach wie vor überzeugt, dass AngularJS eine gute Wahl ist, obwohl die Versionspolitik diese Freude leicht getrübt hat.
EmberJS konnte mich persönlich im Vergleich noch nicht so überzeugen, es ist aber nichtdestotrotz ähnlich mächtig wie AngularJS. Insbesondere ist es, falls Sie einen Background in der Rails Entwicklung haben und mit der dort vorherrschenden Convention over Configuration Philosophie vertraut sind, eine ausgezeichnete Wahl.
KnockoutJS ist dann eine ganze Ecke kleiner als die beiden Kontrahenten, macht aber genau deswegen Spaß! Nicht nur für kleinere Projekte und für die Strukturierung von auf Legacy jQuery Code basierende Projekte eine exzellente Wahl.
Als weiterer interessanter Kandidat hat sich in den letzten Monaten mit Facebooks react.js hervorgetan, den man sicherlich im Auge behalten muss.