Views
Batman.View
is the bridge between application state and user interaction.
Views are responsible for rendering templates, handling bindings, and general
manipulation of the DOM. Most of the time, they’ll be automatically created by
bindings within templates, but they can be manually manipulated as well.
The View Hierarchy
Views are organized as a rooted tree structure, similar to that of Cocoa. Each
view keeps track of its parent (superview
) and its direct children
(subviews
). The root of the tree is referred to as the layout view, which
is responsible for the document’s <html>
node. There is one layout view per
App
.
Views as data contexts
The view tree is also used to organize data in a hierarchical way, reminiscent of variable scoping in JavaScript. Properties of a view are accessible to its entire subtree, making it an ideal way to store data relevant to part of the DOM.
Whenever you create a binding with data-bind
or similar, the tree is
traversed to locate the specified keypath (via [View::lookupKeypath]
). The
lookup follows this chain:
current view → chain of superviews → layout view → active controller → app → window
Adding views to the DOM
Views are added to the DOM by adding them to a superview that is already part
of the DOM. The layout view represents the root <html>
node, so it is always
in the DOM.
When adding a subview, you need to specify where exactly in the superview’s DOM
tree the subview should be appended. To do this, set the parentNode
property
on the subview. This can either be a node contained in the superview’s DOM tree
already or a string selector to find one.
Alternatively, you may set the contentFor
property on a subview. This uses
batman.js’ traditional yield
system and will replace the yield node’s content
with the subview’s node
. You should set contentFor
to a string matching the
name of the yield
in the subview.
View Lifecycle
As a view is manipulated by the application, it progresses through various states. As it does this, it fires events that you can hook into:
viewWillAppear
: Fired when the view is about to be attached to the DOM. It will always have a superview.viewDidAppear
: Fired when the view has just been attached to the DOM. Its node is on the page, and could be selected withdocument.querySelector
.viewWillDisappear
: Fired when the view is about to be detached from the DOM. It will still have a superview set.viewDidDisappear
: Fired when the view has just been detached from the DOM. Its node is no longer part of the page, and may not be selected from the document. If it was removed directly it will not have a superview, and if an ancestor was removed it will still have a superview.viewDidMoveToSuperview
: Fired when the superview property is changed to a valid view, regardless of whether that superview is in the DOM or not.viewWillRemoveFromSuperview
: Fired when the subview is going to be removed from its superview, regardless of whether that superview is in the DOM or not.viewDidLoad
: AfterloadView
has been successfully called, the div has been created and populated with HTML from theHTMLStore
.ready
: All bindings have been initialized (one shot).
Custom Views
Views are useful for creating reusable, configurable components which can be instantiated from within templates.
<examples go here>
Backing Views
Some of the more complex bindings will create a new View
(or many) to allow
them to manage the DOM. Such views are called backing views. For example,
using data-foreach
will create a backing view for each item being iterated
over, containing a reference to the item for that iteration.
Loading Views
Views are not parsed or added to the DOM when they’re first constructed. Instead, they’re lazily loaded when you perform certain operations on them.
- If a view is in the DOM, adding to its subview set will cause the subview and its entire subtree to be added to the DOM. Removing a subview will automatically remove it from the DOM.