2. In plain HTML we end up writing long and repetitive
structures.
CSSs can help reducing styling rules to simple Tag
classes.
Still in non naïve situations the
structure can be confusing.
The Problem
HTML TEMPLATES ORGANIZATION
3. We have HTML elements that hide complex structures.
Here are some examples:
• SELECT
• File INPUT
• VIDEO
The Question
HTML TEMPLATES ORGANIZATION
4. The SELECT element hides the definition of a complex
and structured UI.
<select>
<option value="volvo">Volvo</option>
<option value="saab">Saab</option>
<option value="opel">Opel</option>
<option value="audi">Audi</option>
</select>
The Question
HTML ELEMENTS
5. The File INPUT element hides the definition of a
complex UI and behavior.
<input type="file">
The Question
HTML ELEMENTS
6. The VIDEO element hides the definition of a complex
structured UI and behavior.
<video width="320" height="240" controls>
<source src="movie.ogg" type="video/ogg">
</video>
The Question
HTML ELEMENTS
7. Can we define our own custom elements?
The Question
HTML CUSTOM ELEMENTS
8. Yes We Can
Defining custom elements we can organize the
structure of an application in a more clean way.
<main-menu></main-menu>
<todo-list></todo-list>
A Solution
HTML CUSTOM ELEMENTS
9. In Knockout.js it is possible to define components.
“Components are a powerful, clean way of organizing
your UI code into self-contained, reusable chunks.”
These allow the developer to better structure both the
Views and the View-Models of the application.
Knockout.js
COMPONENTS
10. In Knockout.js new components are defined in the
following way.
ko.components.register(<the component name>, {
template: <the template used in the component>
});
The component name is any non empty string.
The template describes the HTML structure that will be
used to render the component.
Components
THE DEFINITION
11. The Template of the component can be passed to the
register function in may ways:
• Template ID
• String
• …
Components
THE DEFINITION - TEMPLATE
12. The Template of the component can be a template ID.
In HTML it is possible to define templates in the following way.
<template id="my-component-template">
<h1>Title</h1>
<button>
Click me right now
</button>
</template>
In the register function it can be passed as follow.
template:{element: 'my-component-template'}
Components
THE DEFINITION - TEMPLATE
13. The Template of the component can be a string.
'<h1>Title</h1><button>Click me right now</button>'
In the register function it can be passed as follow.
template: '<h1>Title</h1> … </button>'
Components
THE DEFINITION - TEMPLATE
14. The Component can have an optional ViewModel that
allow one to define custom properties and events.
ko.components.register(<the component name>, {
template: <the template used in the component>
viewModel: <ViewModel constructor>
});
Components
THE DEFINITION - VIEWMODEL
15. Once the Component has been defined it can be used
via the component binding.
<div data-bind='component: "<name>"'></div>
Components
THE DEFINITION - USAGE
16. It is possible to pass data to the component using a
params property in the component binding.
<div data-bind='component: {
name: "<name>",
params: { … }
}'></div>
Components
THE DEFINITION - PARAMS
17. The defined parameters are the first argument passed
to the ViewModel constructor
function ViewModel(params) {
…
}
Components
THE DEFINITION - PARAMS
18. In Knockout.js it is possible to include components
into the views using custom elements.
“Custom elements are an optional but convenient
syntax for consuming components.”
These make the Views more readable and self
explaining.
Knockout.js
CUSTOM ELEMENTS
19. A custom element can be included into the HTML as a
normal element.
<div data-bind='component: {
name: "<component-name>",
params: { … }
}'></div>
Becomes
<component-name params=" … "></component-name>
Knockout.js
COMPONENTS - USAGE
20. A SPA (Single Page Application) is an application
developed with client-side technologies that, instead of
reloading the page when navigating from one area to
another, dynamically changes the structure of the page to
reflect the navigation.
In SPAs a common problem is Routing.
We would like keep the URL-based nature of the web while
redirecting requests to different URLs to different areas of
the same application.
Routing
SINGLE PAGE APPLICATIONS
21. For Knockout.js is available a library that exploits
components for manage routing.
ko-component-router
https://github.com/caseyWebb/ko-component-router
Routing
A COMPONENT BASED APPROACH
22. ko-component-router is a library based on page.js that
organizes the areas of the SPA in components.
Each component describes a different area.
The navigation from one area to another triggers the
disposal of the active component and the instantiation of
the component responsible of the target one.
Routing
A COMPONENT BASED APPROACH
23. In a SPA based on ko-component-router the area that will
be updated on navigation is marked by a particular
element.
<ko-component-router></ko-component-router>
The initialization of the router is done by
ko.router.start();
Routing
INITIALIZATION
24. Components describing an application area are defined as
usual.
The only difference is in the ViewModel initialization where
instead of the params object a context is passed.
The context represents the current state of the application.
function HomeViewModel(ctx) {
…
}
Routing
DEFINE COMPONENTS
25. A Route is an access point for the application.
It is defined by the Path and the component that will
manage the matching requests.
ko.router.route(<path>, <component>)
Example
ko.router.route('/home', 'Home')
Routing
DEFINE ROUTES
26. What can be used as a Path?
A Path can be a simple string describing the address.
'/some/folder/in/the/path‘
It can contain Wildcards
'/*‘
It can be a Regular Expression
/^/commits/(d+)..(d+)/
Routing
DEFINE ROUTES
27. In the path of a page we can define Parameters.
A Parameter is a part of the path that can match a string.
The current value of the parameter is passed to the
Component ViewModel.
ko.router.route('/user/:user_id', 'UserDetails')
The parameter is accessible from the context
function UserDetailsViewModel(ctx) {
… ctx.params.user_id …
}
Routing
ROUTE PARAMETERS
28. While normal links can be used it is better to use the
custom route binding.
<a href="/user/1234">John Doe</a>
Becomes
<a data-bind="route: '/user/1234'">John Doe</a>
This allow one to compute the target route dynamically as it
can be computed based on Knockout.js Observables.
Routing
NAVIGATION