part 5
Often, you’ll be using one of FOAM’s generic controllers, which can handle
navigation for you. In this tutorial, we’ll do navigation by hand to demonstrate
more advanced templates, the View
lifecycle, and other concepts.
We’ll begin by expanding the ControllerView
to make the decision of whether to
show us a single phone’s page or the list. Expand it to look like this:
Note that our original ControllerView
template is now the else
branch, ie.
what will be shown when window.location.hash
is empty.
- We’re navigating by setting
window.location.hash
to theid
of the phone we want to see. - We can put real Javascript control structures inside
<% %>
tags, and indeed theif
branch is written entirely in Javascript. - In that first branch, we create a
PhoneDetailView
, which we’ll define shortly. We tell it whatmodel
it should be the view for, but not what object is currently being viewed. - All views have
addChild
, which adds another view to a list of child views. The defaultinitHTML
(see below) will callinitHTML()
on all the child views recursively. - We look up the phone in the master
dao
, not the filtered one.find(id, sink)
will locate a single item by its ID.- The
id
of the phone we want to find is the hash, with the leading#
chopped off. - We provide a custom
sink
, which is just a Javascript object with aput
function.put
will be called, if defined, when a DAO finds an object matching a query. - When the phone is found, the DAO will call our sink’s
put
function with thePhone
object. Ourput
will setview.data
to the phone, and thePhoneDetailView
will automatically update itself to display this new data.
- The
- We also add an
init
method. This is similar to a constructor and is called duringControllerView.create()
. It is very important to callthis.SUPER()
first thing in any custominit
we write, since the parent classes do several important things ininit
. - Our
init
adds a listener to thehashchange
event, which will re-render the template into the page. DOM templates have a two-step lifecycle:toHTML()
is the main template function. It returns a string which gets added to the DOM.initHTML()
needs to run after everything is added to the DOM. It hooks up any listeners, callsinitHTML
recursively on children, and so on. You generally won’t need to write custominitHTML
methods.
Now we need to define PhoneDetailView
. As we did before, let’s simply define
it as an empty subclass of DetailView
:
That will be enough to let us reload the page and see it working, though it will be ugly as before.
Try it! Click on a phone in the catalog, and you will switch to its detail view. Use your browser’s Back button, and you’re back at the catalog.
Part 6 shows external templates and
explores DetailView
s further.