Extending your ExpressionEngine Add-Ons with KnockoutJS
Learn how to use KnockoutJS to build dynamic web apps and integrate it with the ExpressionEngine CMS as a custom module. Originally presented at EECI 2012
"code monkey" doing .NET/C# development for Chase and software firms Sophos and TDCI Worked in web dev when altavista and yahoo was everybody's search engine.
to ignore the front-end experience Story: faced with a mess of a project, home sale calculator dozens of different calculations all interdependent with each other. Wrapped up in an obsolete "windows" js library A friend suggested KO, i was able to turn a 2.5 month project into a one month job.
• Dependency tracking • Declarative binding • Extensible • Supports lots of browsers Sunday, October 21, 2012 KnockoutJS is a javascript library that helps you create dynamic web applications. Anytime you have anything in your UI change dynamically, KO will help you write and maintain that Dependency tracking: ko detects changes in your data and syncs it to your ui automatically Declarative bindings: any easy way to connect your UI to your data, if you can write Html you can bind with ko Extensible: write your own custom code to make KO even more powerful Browser support: supports IE 6+, Safari, Firefox, Chrome
app gets bigger • As complexity increases so does the number of things the dev has to manage Sunday, October 21, 2012 But as your app gets more complex, managing all of those low level pieces becomes a challenge It could become so great that your app collapses under its own weight, simply because there isnt a clean way to separate your app's data and logic from the UI
data and UI in sync • You can still use jQuery with KO Sunday, October 21, 2012 KO scales well because it's a high-level framework that takes care of the manual labor of keeping your data and UI in sync. jQuery and KO play very well together, and KO doesn't interfere with your underlying HTML or how you design your app.
keep a complex app simple by using three components Sunday, October 21, 2012 The way ko organizes your application is by using the Model View View Model pattern, MVVM for short
Model = Model + methods that do work • View = UI, aka HTML doc (or EE template) • Demo : jsfiddle.net/tNb64 Sunday, October 21, 2012 There are three components in MVVM: Model - this is the data your app will manage, usually loaded from a database with ajax calla View Model - view model is your apps data, plus methods that manipulate the data. These methods should be independent of the UI, this keeps your code simple as your app becomes more complex View - finally your view is your apps ui, this would be your HTML or EE template. The view displays information in the model and sends commands to the View Model based on user behavior (such as button clicks) Lets see a simple example of the pattern
the ViewModel changes • Setup with "ko.observable()" • To read, call observable property as a method: this.firstName() • To update, pass value as a param: this.firstName("Patrick") • Demo: jsfiddle.net/KxMfX/1 Sunday, October 21, 2012 So you've seen how to create a ViewModel and display one of it's properties using a binding. One of KO's main benefits is how it can update the UI automatically when the ViewModel changes. But how does it know when the ViewModel changes? The answer is a key concept in KO called an observable. Observables watch for changes in the state of properties in the View Model and updates the View automatically You create using ko.observable() Read by calling the property as a method, empty param: this.firstName() Update by passing the value as a param to the method: thsi.firstName("Patrick")
• Computed observables can be combines with other computed observables • Demo: jsfiddle.net/patpohler/ usM4k Sunday, October 21, 2012 So what if you have an observable for first name and one for last name and you wanted to display a full name? That's where the Computed Observable comes in handy. Like Voltron, a computed observable is a function combines one or more other observables together. Even other computed observables! Lets see it in action
ViewModel into the computed observable to define "this" keyword • Tip: set "this" to a variable in the ViewModel as a reference • Demo: http://jsfiddle.net/ GpPKM/2/ Sunday, October 21, 2012 Notice that i passed the keyword "this" as a second parameter to ko.computed. This maps the "this" keyword to the instance of the View Model.. Otherwise the observable would have no idea what "this.firstName()" was There's a programming convention i recommend thats easier to understand, heres a quick demo
• Only tracks object IN the array, not changes to the objects themselves • Add items with "push" • Demo: jsfiddle.net/patpohler/ CEKKW Sunday, October 21, 2012 Finally our last type of observable deals with tracking collections or arrays of objects. Like the Count from Sesame st, observable arrays watch when items are added and subtracted from the collection. They do not track changes to the properties in those objects, you'll need to define those properties as their own observables Lets see a demo
the View and View Model interact • Affect Text & Appearance, Control Flow, and Form Fields • You can even create your own custom bindings Sunday, October 21, 2012 So we've seen in our examples a couple of KO's bindings. Remember, bindings are just simple methods KO uses to control how the View and ViewModel interact with each other. These bindings can be broken down into three categories. Text & Appearance, Control Flow and Form fields. You can even create your own custom bindings for some really advanced functionality. Right now, let's talk about some of the more common bindings you'll use in your app.
array and binds elements to markup inside • $index gets the position, $data returns current element, $parent is the containing object • Demo: http://jsfiddle.net/ patpohler/CEKKW/1 Sunday, October 21, 2012
conditional • Adds & removes elements to the DOM, doesn't just hide them • Use "ifnot" for negative conditionals • Demo: http://jsfiddle.net/ patpohler/7Nnbt/1 Sunday, October 21, 2012
Javascript objects or JSON to KO models • Use ko.mapping.fromJS to convert a JS object to a KO view model • ko.mapping.toJS will convert a KO object to a regular object Sunday, October 21, 2012