|
1 | | -## JsViews: Next-generation MVVM and MVP framework - bringing templates to life |
2 | | -_The power of MVVM, the flexibility of JavaScript, the speed and ease of JsRender templates and jQuery_<br/> |
| 1 | +## JsViews: next-generation MVVM and MVP framework - bringing templates to life |
| 2 | +*The power of MVVM, the flexibility of JavaScript, the speed and ease of JsRender templates and jQuery*<br/> |
3 | 3 |
|
4 | | -**JsViews** builds on top of **[JsRender](http://www.jsviews.com/#jsrender)** templates, and adds data-binding and **[observable data](http://www.jsviews.com/#jsobservable)**, to provide a fully-fledged MVVM platform for easily creating interactive data-driven single |
5 | | - page apps and websites. |
| 4 | +**JsViews** builds on top of **[JsRender](http://www.jsviews.com/#jsrender)** templates, and adds data-binding and **[observable data](http://www.jsviews.com/#jsobservable)**, to provide a fully-fledged MVVM platform for easily creating interactive data-driven single-page apps and websites. |
6 | 5 |
|
7 | | -**JsRender** and **JsViews** together provide the next-generation implementation of both _JQuery Templates_, and _JQuery Data Link_ - and supersede those libraries. |
| 6 | +<h3>Documentation and Downloads</h3> |
| 7 | +**[Documentation](http://www.jsviews.com/#jsviews)**, **[downloads](http://www.jsviews.com/#download)**, **[samples](http://www.jsviews.com/#samples)** and **[API docs and tutorials](http://www.jsviews.com/#jsvapi)** are available on the **[www.jsviews.com website](http://www.jsviews.com/#jsviews)**. |
8 | 8 |
|
9 | | -See also the _[JsRender](https://github.com/BorisMoore/jsrender)_ repository on GitHub<br/> |
| 9 | +The content of this ***ReadMe*** is available also as a *[JsViews Quickstart](http://www.jsviews.com/#jsv-quickstart)*. |
10 | 10 |
|
11 | | -<h3>Documentation and Downloads</h3> |
12 | | -**[Documentation](http://www.jsviews.com/#jsviews)**, **[downloads](http://www.jsviews.com/#download)**, |
13 | | - **[samples](http://www.jsviews.com/#samples)** are available on the **[www.jsviews.com website](http://www.jsviews.com/#jsviews)**. |
14 | | -<br/>(JsViews and JsObservable **API docs and tutorials** are coming soon, as we move JsViews to the official beta and on to V1.0) |
| 11 | +<h3>JsRender and JsViews</h3> |
| 12 | +**JsRender** is used for data-driven rendering of templates to strings, ready for insertion in the DOM. (See [JsRender Quickstart](http://www.jsviews.com/#jsr-quickstart) and [JsRender GitHub repository](https://github.com/BorisMoore/jsrender)). |
| 13 | + |
| 14 | +**[JsRender](https://github.com/BorisMoore/jsrender)** and **[JsViews](https://github.com/BorisMoore/jsviews)** together provide the next-generation implementation of the official jQuery plugins *[JQuery Templates](https://github.com/BorisMoore/jquery-tmpl)*, and *[JQuery Data Link](https://github.com/BorisMoore/jquery-datalink)* -- and supersede those libraries. |
| 15 | + |
| 16 | +<h2>JsViews Usage</h2> |
| 17 | + |
| 18 | +<h3><i>Data-linked templates</i></h3> |
| 19 | + |
| 20 | +JsViews provides *data-linking* - so that JsRender templates become data-bound: |
| 21 | + |
| 22 | +- *Data-linked* tags or elements in your templates will update automatically whenever the underlying data changes. |
| 23 | +- Some data-linked tags or elements provide *two-way* data-linking, so that user interactions will trigger *"observable"* changes to the underlying data (which may then trigger other updates elsewhere in your templated UI). |
| 24 | + |
| 25 | +**Data-linked template tags:** |
| 26 | + |
| 27 | +Any JsRender tag, `{{...}}` can be *data-linked* by writing `{^{...}}`, as in: |
| 28 | + |
| 29 | +```html |
| 30 | +<ul> |
| 31 | + {^{for people}} <!-- List will update when people array changes --> |
| 32 | + <li>{^{:name}}</li> <!-- Will update when name property changes --> |
| 33 | + {{/for}} |
| 34 | +</ul> |
| 35 | +``` |
| 36 | + |
| 37 | +[Learn more...](http://www.jsviews.com/#linked-tag-syntax) |
| 38 | + |
| 39 | +**Data-linked HTML elements:** |
| 40 | + |
| 41 | +HTML elements within templates can be *data-linked* by adding a `data-link` attribute: |
| 42 | + |
| 43 | +```html |
| 44 | +<input data-link="name"/> <!-- Two-way data-binding to the name property --> |
| 45 | +<span data-link="name"></span> <!-- Will update when name property changes --> |
| 46 | +``` |
| 47 | + |
| 48 | +HTML elements within 'top-level' page content can also be data-linked -- see [below](#jsv-quickstart@toplink). |
| 49 | + |
| 50 | +[Learn more...](http://www.jsviews.com/#linked-elem-syntax) |
| 51 | + |
| 52 | +<h3><i>Render and link a template</i></h3> |
| 53 | + |
| 54 | +With *JsRender*, you call the `render()` method, then insert the resulting HTML in the DOM. |
| 55 | + |
| 56 | +```js |
| 57 | +var html = tmpl.render(data, helpersOrContext); |
| 58 | +$("#container").html(html); |
| 59 | +``` |
| 60 | + |
| 61 | +With *JsViews*, you can instead call the `link()` method: |
| 62 | + |
| 63 | +```js |
| 64 | +tmpl.link("#container", data, helpersOrContext); |
| 65 | +``` |
| 66 | + |
| 67 | +which in one line of code will: |
| 68 | +- render the template |
| 69 | +- insert the resulting HTML as content under the HTML `container` element |
| 70 | +- data-link that content to the underlying `data` |
| 71 | + |
| 72 | +Now *observable* changes in the data will automatically trigger updates in the rendered UI. |
| 73 | + |
| 74 | +There are two ways of calling the `link()` method: |
| 75 | +- If you have a reference to the <em>template object</em>, call [`template.link(...)`](http://www.jsviews.com/#jsvtmpllink) |
| 76 | +- If you have registered the template by name (`"myTmpl"`), call [`link.myTmpl(...)`](http://www.jsviews.com/#jsv.d.link) |
| 77 | + |
| 78 | +**Example**: - Template from string |
| 79 | + |
| 80 | +```js |
| 81 | +var tmpl = $.templates("{^{:name}} <input data-link='name' />"); |
| 82 | +var person = {name: "Jim"}; |
| 83 | +tmpl.link("#container", person); |
| 84 | +``` |
| 85 | + |
| 86 | +**Example**: - Template from script block |
| 87 | + |
| 88 | +```html |
| 89 | +<script id="myTemplate" type="text/x-jsrender"> |
| 90 | +{^{:name}} <input data-link="name" /> |
| 91 | +</script> |
| 92 | +``` |
| 93 | + |
| 94 | +```js |
| 95 | +var tmpl = $.templates("#myTemplate"); |
| 96 | +var person= {name: "Jim"}; |
| 97 | +tmpl.link("#container", person); |
| 98 | +``` |
| 99 | + |
| 100 | +**Example**: - Named template from string |
| 101 | + |
| 102 | +```js |
| 103 | +$.templates("myTmpl1", "{^{:name}} <input data-link='name' />"); |
| 104 | +var person= {name: "Jim"}; |
| 105 | +$.link.myTmpl1("#container", person); |
| 106 | +``` |
| 107 | + |
| 108 | +**Example**: - Named template from script block |
| 109 | + |
| 110 | +```html |
| 111 | +<script id="myTemplate" type="text/x-jsrender"> |
| 112 | +{^{:name}} <input data-link="name" /> |
| 113 | +</script> |
| 114 | +``` |
| 115 | + |
| 116 | +```js |
| 117 | +$.templates("myTmpl2", "#myTemplate"); |
| 118 | +var data = {name: "Jim"}; |
| 119 | +$.link.myTmpl2("#container", data); |
| 120 | +``` |
| 121 | + |
| 122 | +**Result:** After each `link()` example above the `container` element will have the following content: |
| 123 | + |
| 124 | +```html |
| 125 | +Jim <input value="Jim" /> |
| 126 | +``` |
| 127 | + |
| 128 | +with the `name` property of `person` object data-linked to the `"Jim"` text node and *two-way* data-linked to the `<input />` |
| 129 | + |
| 130 | +See: [Playing with JsViews](http://www.jsviews.com/#jsvplaying) for working samples, such as [this one](http://www.jsviews.com/#jsvplaying@twoway) |
| 131 | + |
| 132 | +[Learn more...](http://www.jsviews.com/#jsvlinktmpl) |
| 133 | + |
| 134 | +<h3 id="jsv-quickstart@toplink"><i>Top-level data-linking</i></h3> |
| 135 | + |
| 136 | +You can use data-linking not only for templated content, but also to data-bind to top-level HTML content in your page: |
| 137 | + |
| 138 | +```js |
| 139 | +$.link(true, "#target", data); |
| 140 | +``` |
| 141 | + |
| 142 | +This will activate any declarative data-binding (`data-link="..."` expressions) on the target element - or on elements within its content. |
| 143 | + |
| 144 | +[Learn more...](http://www.jsviews.com/#toplink) |
| 145 | + |
| 146 | +<h3><i>Making "observable" changes to objects and arrays</i></h3> |
| 147 | + |
| 148 | +In current JavaScript implementations, modifying objects or arrays does not raise any event, so there is no way for the change to be detected elsewhere. JsViews dynamic data-bound UI solves this through <em>data-linking</em>, using the <em>JsObservable observer pattern</em>. |
| 149 | + |
| 150 | +The JsViews `$.observable()` API provides a way for you to change objects or arrays <em>observably</em>. Each change will raise a <a href="http://www.jsviews.com/#onpropchange">property change</a> or <a href="http://www.jsviews.com/#onarrchange">array change</a> event. |
| 151 | + |
| 152 | +**Modify an object observably** |
| 153 | + |
| 154 | +```js |
| 155 | +$.observable(person).setProperty("name", newName); |
| 156 | +``` |
| 157 | + |
| 158 | +`$.observable(person)` makes the `person` object *"observable"*, by providing a `setProperty(...)` method. Use `setProperty` to change a value, and the change will be *"observed"* by the declarative data-binding in the template. |
| 159 | + |
| 160 | +**Modify an array observably** |
| 161 | + |
| 162 | +```js |
| 163 | +$.observable(people).insert(newPerson); |
| 164 | +``` |
| 165 | + |
| 166 | +`$.observable(people)` makes the `people` array *"observable"*, by providing methods like `insert(...)` and `remove(...)`. Use them to make changes to arrays, and the changes will be *"observed"* by data-bound elements and tags in the template - such as the `{^{for dataArray}}` tag. |
| 167 | + |
| 168 | +[Learn more...](http://www.jsviews.com/#$observable) |
| 169 | + |
| 170 | +<h3><i>Responding to data changes</i></h3> |
| 171 | + |
| 172 | +JsViews uses the *<a href="http://www.jsviews.com/#onpropchange">property change</a>* or *<a href="http://www.jsviews.com/#onarrchange">array change</a>* events to make any <a href="http://www.jsviews.com/#linked-template-syntax">data-linked tags or elements</a> in your templates update automatically in response to each *observable* change in your underlying data. In addition, with two-way data-linking, it ensures that those events are raised when the user interacts with a data-linked template, and causes changes to the underlying data. |
| 173 | + |
| 174 | +**observe() and observeAll()** |
| 175 | + |
| 176 | +The [$.observe()](http://www.jsviews.com/#observe) and [$.observable().observeAll()](http://www.jsviews.com/#observeAll) APIs make it very easy for you to register event handlers or listeners, so your code can listen to specific observable changes made to your data objects or view models: |
| 177 | + |
| 178 | +```js |
| 179 | +$.observe(person, "name", function(...) { |
| 180 | + // The "name" property of person has changed |
| 181 | + ... |
| 182 | +}); |
| 183 | +``` |
| 184 | + |
| 185 | +```js |
| 186 | +$.observable(person).observeAll(function(...) { |
| 187 | + // A property of person, or a nested object property, has changed |
| 188 | + ... |
| 189 | +}); |
| 190 | +``` |
| 191 | + |
| 192 | +[Learn more...](http://www.jsviews.com/#observeobjectsarrays) |
| 193 | + |
| 194 | +<h3><i>Accessing the view hierarchy</i></h3> |
| 195 | + |
| 196 | +Each instance of a rendered template or a template block tag is associated with a JsViews *"view"* object -- so nested tags lead to a hierarchy of view objects. The [view hierarchy](http://www.jsviews.com/#views) shows how the underlying data objects map to the rendered UI. |
| 197 | + |
| 198 | +**From UI back to data:** |
| 199 | + |
| 200 | +Use [`$.view(elem)`](http://www.jsviews.com/#jsv.d.view) to get from a DOM element to the corresponding `view` object for that part of the rendered content. From the `view` you can then get to the underlying `data`, the `index`, etc. |
| 201 | + |
| 202 | +*[Example](http://www.jsviews.com/#jsv.d.view@$view):* |
| 203 | + |
| 204 | +```html |
| 205 | +{^{for people}} |
| 206 | + ... |
| 207 | + <button class="changeBtn">Change</button> |
| 208 | + ... |
| 209 | +{{/for}} |
| 210 | +``` |
| 211 | + |
| 212 | +Click-handler code for <em>Change</em> button: |
| 213 | + |
| 214 | +```js |
| 215 | +$(".changeBtn").on("click", function() { |
| 216 | + // From the clicked HTML element ('this'), get the view object |
| 217 | + var view = $.view(this); |
| 218 | + |
| 219 | + // Get the 'person' data object for clicked button |
| 220 | + var person = view.data; |
| 221 | + |
| 222 | + // Get index of this 'item view'. (Equals index of person in people array) |
| 223 | + var index = view.index; |
| 224 | + |
| 225 | + // Change the person.name |
| 226 | + $.observable(person).setProperty("name", person.name + " " + index); |
| 227 | +}); |
| 228 | +``` |
| 229 | + |
| 230 | +[Learn more...](http://www.jsviews.com/#$view) |
| 231 | + |
| 232 | +<h3><i>Documentation and APIs</i></h3> |
| 233 | + |
| 234 | +See the [www.jsviews.com](http://www.jsviews.com) site, including the [JsViews Quickstart](http://www.jsviews.com/#jsv-quickstart), [JsViews APIs](http://www.jsviews.com/#jsvapi) and [JsObservable APIs](http://www.jsviews.com/#jsoapi)topics. |
15 | 235 |
|
16 | | -<h3>Demos</h3> |
17 | | -In addition to the demos at [www.jsviews.com/#samples](http://www.jsviews.com/#samples), see also the [demos](https://github.com/BorisMoore/jsviews/tree/master/demos) folder of this GitHub repository - available [here](http://borismoore.github.io/jsviews/demos/index.html) as live samples. |
| 236 | +<h3><i>Demos</i></h3> |
| 237 | +Demos and samples can be found at [www.jsviews.com/#samples](http://www.jsviews.com/#samples), and throughout the [API documentation](http://www.jsviews.com/#jsvapi). |
18 | 238 |
|
19 | | -<h3>Current Status</h3> |
20 | | -JsViews is now a beta candidate release, which will be declared beta as soon as API documentation is complete on the [www.jsviews.com](http://www.jsviews.com) website, and then move to V1.0. |
| 239 | +(See also the [demos](https://github.com/BorisMoore/jsviews/tree/master/demos) folder of the GitHub repository - available [here](http://borismoore.github.io/jsviews/demos/index.html) as live samples). |
0 commit comments