view.json

High level markup

The HL markup is a layer that builds on top of the more simple low level markup.

It is intended to be a more human-friendly and enhanced environment, which trades off understanding the details with productivity.

Nested views

<div name="Foo">
  <div name="Bar"></div>
</div>

References to names

Bindings use names to locate their target models.

There are two types of references:

  1. Relative references. These start with a dot, e.g. .title. They always refer to properties of the model associated with the current view.
  2. Full names. These are resolved within the global scope, e.g. App.Foo.Bar.

For example:

<div name="Greeting">Hello {{.name}}</div>

refers to view.model.get("name") while:

<div name="Greeting">Hello {{App.name}}</div>

refers to scope.get('App.name').

Bindings

Content binding (bind)

<div name="Greeting">Hello <span bind="User.name" /></div>

The value of "User.name" is shown after "Hello " in the view Greeting.

When the value of "User.name" changes (e.g. when the "User.name" event is triggered), the value is updated.

Class binding (bind-class)

<ul name="TodoList" template="collection">
  <li name="Todo" bind-class-done="model.done">Hello</li>
</ul>

The class "done" is bound to the value of "model.done" in the scope of the view.

If the expression is true, then the class is added. If the expression is false, then the class is removed.

When the value of model.done changes, the expression is recalculated.

CSS binding (bind-css)

<ul name="TodoList" template="collection">
  <li name="Todo" bind-css-color="model.value > 100 ? 'green' : 'red'">Hello</li>
</ul>

Value binding (bind-value)

<div name="Document">
  <input type="text" bind-value="model.heading" />
</div>

The value of "Document.model.heading" is bound to the value of the input.

When the value of model.heading changes, the value of the input changes.

The value binding is a two-way binding for the following elements: text, password, textarea, select.

Attribute binding (bind-attr)

<div name="Document">
  <input type="text" bind-attr-value="model.heading" />
</div>

Visibility binding (bind-visible)

<div name="Remaining" bind-visible="Todos.length > 0">
  Remaining items: <span bind="Todos.length" />
</div>

When the value of Todos.length > 0, the Remaining view is visible. When Todos.length <= 0, the view is hidden.

if-else

<switch>
  <case>
    <div> ... </div>
  </case>
  <default>
    <div> ... </div>
  </default>
</switch>

Collections

<ul name="TodoList" template="collection" bind="Todos">
  <li name="Todo" bind-class-done="model.done">Hello</li>
</ul>

Note the need to specify bind="Todos".

Otherwise it would be hard to initialize nested views.

Swappables

Essentially, views that act as placeholders for other views or view hierarchies.

Handling DOM events

Trivial - most events. Nontrivial: "return" keypress.

Passing a current item

Doable via:

view.model

Or via a name lookup.

Accessing the event object

Via the evt param.