Skip to content

toolkitchen/mdv

 
 

Repository files navigation

Learn the tech

What is Model-driven Views?

Model-driven Views (or "MDV" for short) is a way to write dynamic HTML using HTML.

Status

MDV is currently available as a JavaScript library and we aim to make it a web standard which is natively implemented by browsers.

MDV works best with three new web platform features, all of which aren't implemented by all browsers (more on this below). If you'd like to experience the best MDV has to offer, try the samples out in the Chrome Canary and turn on Enable Experimental JavaScript in chrome://flags.

An explanatory sample

There's plenty of detail, but it all hinges on the <template> element. Let’s walk through a simple example which demonstrates the basics.

<head>
  <script src="mdv.js"></script>
</head>
<body>
  <h1>Model-driven Views</h1>
  <ul>
    <template id="greeting" repeat="{{ salutations }}">
      <li>{{ what }}: <input type="text" value="{{ who }}"></li>
    </template>
  </ul>
<script>
var t = document.getElementById('greeting');
var model = {
  salutations: [
    { what: 'Hello', who: 'World' },
    { what: 'GoodBye', who: 'DOM APIs' },
    { what: 'Hello', who: 'Declarative' },
    { what: 'GoodBye', who: 'Imperative' }
  ]
};
t.model = model;
</script>
</body>

This example should look mostly familiar to anyone who knows HTML, but there are a couple novel things going on:

The <template> element

The HTML Template element is new and browsers are in the process of implementing it. It allows you to declare fragments of HTML that may be used at some point. The Chrome Inspector allows you see the content of a template element.

ScreenShot

If you loaded the above example without <script src="src/mdv.js"></script>, that’s about all <template> would do.

However, the MDV library teaches <template> some new tricks. With MDV, <template> knows how to:

  • Instruct DOM nodes to derive their value from JavaScript data by binding them to the data provided.
  • Maintain a fragment of DOM (or "instance fragment") for each item in an array.
  • Conditionally stamp out one or more instance fragments, based on whether some data value is true or not.
  • ...And lots more.

But back to the example. Our template...

<template id="greeting" repeat="{{ salutations }}">
  <li>{{ what }}: <input type="text" value="{{ who }}"></li>
</template>

...defines what each instance will look like when stamped out. In this case, it contains a <li> with a text node and an <input> as its children. The mustaches {{ ... }} mean "bind data here". The repeat="{{ salutations }}" tells the template to ensure there is one instance fragment for each element in the salutations array.

In <script>, we create a model:

var model = {
  salutations: [
    { what: 'Hello', who: 'World' },
    { what: 'GoodBye', who: 'DOM APIs' },
    { what: 'Hello', who: 'Declarative' },
    { what: 'GoodBye', who: 'Imperative' }
  ]
};

Notice that this is just JavaScript data: there’s no need to import your data into special observable objects. The template is set in motion by binding the model data to it:

t.model = model;

Now the template is off to the races. Here's the result:

ScreenShot

and here's what the DOM looks like:

ScreenShot

You can see that the template stamped out four instances immediately following its position in the document. All nodes within an instance have a property called templateInstance which points to an instance descriptor. The descriptor indicates the extent (first and last nodes) of the instance, as well as the model data for which the instance was produced:

ScreenShot

Now, remember we said MDV teaches the DOM to derive its values from JavaScript data? If we change a value in our model, the DOM observes the change and updates accordingly:

ScreenShot

However, the DOM doesn’t just observe data in the model, if DOM elements which collect user input are bound, they push the collected value into the model:

ScreenShot

Lastly, let's look at what happens when we alter the contents of the model.salutations array:

ScreenShot

The <template> is repeating which means that it ensures there is one instance for each item in the array. We removed two elements from the middle of salutations and inserted one in their place. The <template> responded by removing the two corresponding instances and creating a new one in the right location.

Getting the idea? MDV allows you author your HTML using HTML which contains information about where data goes and directives which control the document’s structure -- all depending on the data you provide it.

Where to go from here?

If you are new to MDV, the best to place to go is to the look at the How-To examples. These are little examples which succinctly demonstrate how to use MDV to accomplish things that frequently are required for real web apps:

Binding to DOM values:

Using <template> to produce DOM structures:

  • Conditionals: How to control whether instance fragments are produced based on the value of a binding.
  • Nested templates: How to accomplish nested template production.
  • Re-using templates: How to define a template once and use it in more than one location.
  • Recursive templates: How to produce tree-structure DOM whose depth is dependent on the data to which it is bound.

API Reference / Pseudo-specs

MDV is designed to as two primitives which could eventually become standardized and implemented natively in browsers. The following two documents specify their behavior, API and use.

Extending MDV

MDV is mainly concerned with being robust and efficient in interacting with application data and keeping the DOM in sync , but more advanced behaviors can be accomplished via one or both of the following:

Advanced Topics

IMPORTANT: The advanced topics documentation have yet to be created.

  • DOM Stability: MDV makes every effort to maintain the state of DOM nodes (event listeners, expandos, etc...). Understand why this is important and how it works.
  • Imperative DOM mutation: You should rarely need to directly manipulate the DOM, but if you do, it’s allowed. Learn the simple rules of how MDV will react if you manipulate the DOM it is managing.
  • Asynchronous processing model: MDV responds asynchronously to changes in data and DOM. Learn why this is good and what it means for your application.
  • Chained observation

Deployment

MDV builds upon recently added primitives to the Web Platform:

Not all browsers currently implement all the required primitives. MDV attempts to polyfil their absence, but targeting browsers which do not support all three requires understanding patterns of use which should be prefered or avoided to ensure proper behavior.

IMPORTANT: The Deploying MDV documentation has yet to be created.

  • Deploying MDV, supported browsers and rough edges

Releases

No releases published

Packages

No packages published