• Stars
    star
    225
  • Rank 171,069 (Top 4 %)
  • Language
    JavaScript
  • License
    MIT License
  • Created over 9 years ago
  • Updated about 9 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

A Virtual DOM based AngularJS view renderer designed to be used with immutable data structures

angular-virtual-dom

npm version Bower version

angular-virtual-dom is an experimental Virtual DOM based AngularJS view renderer designed to be used with immutable data structures such as immutable-js and mori.

angular-virtual-dom lets you use regular AngularJS templates and expressions to bind data to the DOM, but uses Virtual DOM diffing behind the scenes.

angular-virtual-dom supports extensibility using directives - though only with directives that are Virtual DOM aware. That means angular-virtual-dom is not a drop-in substitute for the AngularJS directive compiler, and is meant to be used in limited contexts.

angular-virtual-dom works with AngularJS versions 1.2 and newer.

Usage

angular.module('myModule', ['teropa.virtualDom'])
  .controller('MyCtrl', function($timeout) {
    this.myData = Immutable.fromJS({
      cols: [
        {name: 'One', cssClass: 'one', key: 'one'},
        {name: 'Two', cssClass: 'two', key: 'two'}
      ],
      rows: [
        {one: 'A1', two: 'B1'},
        {one: 'A2', two: 'B2'}
      ]
    });

    // A new version of the immutable data structure triggers
    // DOM diffing later.
    $timeout(function() {
      this.myData = this.myData.updateIn(['rows'], function(rows) {
        return rows.push(Immutable.Map({one: 'A3', two: 'B3'}));
      });
    }.bind(this), 1000);
  });
<div ng-controller="MyCtrl as myCtrl">
  <table v-root="myCtrl.myData">
    <thead>
      <th v-repeat="col in myCtrl.myData.get('cols')"
          class="{{col.get('cssClass')}}">
        {{col.get('name')}}
      </th>
    </thead>
    <tbody>
      <tr v-repeat="row in myCtrl.myData.get('rows')"
          class="{{$even ? 'even' : 'odd'}}">
        <th v-repeat="col in myCtrl.myData.get('cols')">
          {{row.get(col.get('key'))}}
        </th>
      </tr>
    </tbody>
  </table>
</div>
  • v-root establishes a Virtual DOM tree. The table tag and all of its descendants will be rendered using virtual-dom, bypassing Angular's own DOM compiler.
  • Virtual DOM diffing and patching occurs when myCtrl.myData changes. The whole Virtual DOM tree uses a single (reference) watch, and only when it fires does the view re-render. The idea is to attach an immutable data structure on the scope, refer to it in v-root, and let Virtual DOM diffing take care of updates when new versions of the data structure are produced.
  • The expressions within the table are normal AngularJS expressions. However, they are not being watched, and are only re-evaluated when diffing is triggered by the containing v-root.
  • Directives bundled with angular-virtual-dom can be used within the Virtual DOM tree. Custom directives can also be created (see below).

Installation

With NPM / Browserify

npm install angular-virtual-dom

Require the module and include it in your AngularJS modules:

require('angular-virtual-dom')

angular.module('myModule', ['teropa.virtualDom'])

Or just:

angular.module('myModule', [
  require('angular-virtual-dom')
])

With Bower

The library is available as a Bower dependency:

bower install angular-virtual-dom --save

After installation, add one of the following to your loaded scripts:

  • angular-virtual-dom/release/angular-virtual-dom.js
  • angular-virtual-dom/release/angular-virtual-dom.min.js

Finally, include the teropa.virtualDom module in your AngularJS modules:

angular.module('myModule', ['teropa.virtualDom'])

API

v-root

Use the v-root directive in your Angular templates to establish a Virtual DOM. This will short-circuit Angular's normal DOM compilation and build the Virtual DOM template from the contained elements.

The directive accepts an expression, and changes to that expression's value cause the Virtual DOM tree to be re-rendered:

<div v-root="baseData">
  <!--
    Nested DOM structures built into a Virtual DOM
    tree
  -->
</div>

Expressions

Within a v-root, any AngularJS expressions are evaluated whenever DOM diffing occurs:

<div v-root="baseData">
  <h1 class="{{anExpression}}">
    {{anotherExpression}}
  </h1>
</div>

Typically, though not necessarily, the expressions will access data from the data structure referred to in v-root:

<div v-root="baseData">
  <h1 class="{{baseData.headerClass}}">
    {{baseData.headerText}}
  </h1>
</div>

Directives

v-if

Includes the node in the Virtual DOM only when the expression evaluates to a truthy value. Analogous with ng-if.

<div v-root="baseData">
  <h1 v-if="{{baseData.headerText}}">
    {{baseData.headerText}}
  </h1>
</div>

v-repeat

Includes a collection of nodes in the Virtual DOM, for each item in a collection. Analogous with ng-repeat.

Supports at least the following types of collections:

  • immutable-js lists, maps, stacks, ordered maps, sets, and ordered sets.
  • mori lists, seqs, vectors, maps, sets, sorted sets, and queues.
  • JavaScript arrays an objects.

Should additionally support any ES6 iterable collections.

Usage with sequential data structures:

<ul v-root="data">
  <li v-repeat="item in data">
    {{item}}
  </li>
</ul>

Usage with associative data structures:

<ul v-root="data">
  <li v-repeat="(k, v) in data">
    {{k}}: {{v}}
  </li>
</ul>

Additionally makes the special variables $index, $even, and $odd available within the template scope.

Writing Custom Directives

Note: The directive API should be considered highly unstable.

Virtual DOM directives are registered as normal AngularJS directives, but must define a linkVirtual function in the directive definition object. This should be a pure function that take a Virtual DOM node as an argument, and returns a modified Virtual DOM node or collection thereof.

The Virtual DOM nodes used by this library always hold a $scope attribute, referring to the current scope. A directive may create a new scope and attach it to the $scope attribute of the returned node.

Usage with Mutable Data Structures

While angular-virtual-dom is designed to be used with immutable data structures, it is not a hard requirement. Regular, mutable JavaScript data structures and objects work just as well.

You will, however, need to manually trigger re-renders by reassigning v-root to a new value unless your code does so naturally.

Contribution

Use Github issues for requests.

Author

Tero Parviainen (@teropa on Twitter)

Leans heavily on virtual-dom by Matt-Esch.

More Repositories

1

redux-voting-server

Server app for the Full-Stack Redux Tutorial
JavaScript
585
star
2

build-your-own-angularjs

Source Code & Errata for the "Build Your Own AngularJS" book. http://teropa.info/build-your-own-angular
JavaScript
584
star
3

redux-voting-client

Client app for the Full-Stack Redux Tutorial
JavaScript
372
star
4

harmonics-explorer

A UI for exploring the harmonic series of sine waves. Done with Angular 2, @ngrx, Immutable.js
TypeScript
213
star
5

hiccups

A ClojureScript port of Hiccup - a fast library for rendering HTML in ClojureScript
Clojure
206
star
6

to-sting

Object.toSting() polyfill
206
star
7

weq8

A parametric EQ for Web Audio
TypeScript
176
star
8

in-c

A realization of Terry Riley's 1964 composition "In C" as an interactive web app
HTML
117
star
9

nlp

My explorations in natural language processing
Clojure
103
star
10

musicforairports.js

JavaScript
63
star
11

windchimes

TypeScript
60
star
12

schmangular.js

An ad hoc, informally-specified, bug-ridden, slow implementation of half of AngularJS
JavaScript
56
star
13

discreetmusic.js

JavaScript
38
star
14

itsgonnarain.js

JavaScript
36
star
15

ng-gfx-demos

Demos for my NG-BE talk about SVG and Canvas graphics and animations in Angular 2.
TypeScript
36
star
16

generative-music-workshop

A simple seed repo for a workshop on making generative music with Tone.js
JavaScript
24
star
17

elseq

An Angular 2 animation experiment, inspired by the cover art of "elseq" by Autechre
TypeScript
15
star
18

triangle-tessellation

A JavaScript implementation of the triangle tessellation algorithm from the OpenGL specification for tessellation shaders.
TypeScript
15
star
19

lein-flyway

A Leiningen plugin for the Flyway database migration framework
Clojure
14
star
20

metabubbles

A generative art experiment in Angular 2
TypeScript
14
star
21

ngrx-hotload-rc5

minimum viable hot loading setup for Angular rc.5 and @ngrx/store
TypeScript
14
star
22

spectrum-analyser

A Web Audio spectrum analyser
TypeScript
11
star
23

ng-fractals

Angular version of https://swizec.com/blog/animating-svg-nodes-react-preact-inferno-vue/swizec/7311
TypeScript
10
star
24

oscilloscope

A Web Audio oscilloscope
TypeScript
8
star
25

drumkit

JavaScript
8
star
26

sproutcore-tutorial-compojure

Sample project of a Compojure / MongoDB backend for the SproutCore ToDos tutorial
Clojure
6
star
27

zombie-pandemic-tracker

They're coming
Java
4
star
28

redux-space-clockwork

A little generative art experiment with Redux and Immutable.
JavaScript
4
star
29

prolefeed

A simple Clojure library for fetching RSS/Atom feeds
Clojure
4
star
30

web-audio-from-the-ground-up-demos

Demo code for the article series "Web Audio From the Ground Up"
TypeScript
4
star
31

failurous-java

Failurous Java client
Java
3
star
32

failurous-ring

Clojure/Ring client for Failurous
Clojure
3
star
33

pickaxe-notes

Some notes to self from re-reading Pickaxe for Ruby 1.9
Ruby
3
star
34

chime-call-response

JavaScript
3
star
35

lein-gwt

A Leiningen plugin for the GWT compiler
Clojure
3
star
36

stem

A fork of the Eclipse Spatiotemporal Epidemiological Modeler project trunk
Java
2
star
37

rails_learning_specs

Learning Rails internals by writing specs
Ruby
2
star
38

rails-int-hh

Rails Intermediate Course for Haaga-Helia
Ruby
2
star
39

gwt-mxhr

A GWT port of the DUI.Stream library
Java
2
star
40

globetrotter

An HTML canvas based slippy map client for GWT
Java
1
star
41

bitrate-magenta-workshop

JavaScript
1
star
42

saddle

An experimental pure JavaScript port of the GWT layout constraint system
JavaScript
1
star
43

isbn_validator

Ruby
1
star
44

presentations

Presentations I've given / am giving
1
star
45

paip-clj

My explorations of "Paradigms of Artificial Intelligence Programming" in Clojure
Clojure
1
star
46

building-angular

Building angular-like framework for much clearer understanding of the core.
JavaScript
1
star
47

closure-study

Learning Closure libs
JavaScript
1
star