ngTemplate
Follow @dsheiko Star Fork DownloadngTemplate is a light-weight DOM-based template engine, inspired by AngularJS.
mustache.js, Handlebars or _.template are all nice and shiny, until it comes to a form.
With every rending these template engines replace the bound DOM subtree
and the state of inputs gets lost.
ngTemplate treats the DOM carefully. It modifies the exact target nodes gracefully
according to the directives and actual state.
Motivation
- Progressive enhancement friendly: Server-side generated HTML can be fully ready for presentation. During
ngTemplatesynchronization it will be updated according to element directives and a provided state - HTML compliant:
data-*- directives instead of foreign concepts such as{{foo}},[hidden],*ngFor,[(ngModel)] - Concern separation: Presentation state logic decoupled from the view
- Performance:
ngTemplatemodifies DOM nodes by state diff; it touches the DOM only when it's necessary - Easy to catch up: Familiar for Angular folks directives such as
data-ng-if,data-ng-switch,data-ng-forand a few extra intuitive e.g.data-ng-text,data-ng-class - Really small library: minimized gziped size is 4K
- Definitely Typed: IDE checks on the fly if you violate any of declared interfaces (if not the compiler does)
How does it work?
Templates are written with HTML that contains ngTemplate-specific data attributes (data-ng-*):
<form id="heroForm" novalidate>
<div class="form-group">
<label for="name">Name</label>
<input id="name" type="text" class="form-control" required >
<div class="alert alert-danger" data-ng-if="!name.valid">
Name is required
</div>
</div>
<div class="form-group">
<label for="power">Hero Power</label>
<select id="power" class="form-control" required>
<option data-ng-for="let p of powers" data-ng-text="p" >Nothing here</option>
</select>
<div class="alert alert-danger" data-ng-if="!power.valid">
Power is required
</div>
</div>
<button type="submit" class="btn btn-default" data-ng-prop="'disabled', !form.valid">Submit</button>
</form>
ngTemplate synchronizes the template with the passed state. Let's say we have the template HTML within a DOM element,
so we initialize the template like let template = new NgTemplate( el );. Alternatively we can populate
the bounding element with the template from the passed string: let template = new NgTemplate( el, '<i data-ng-if="foo">Hello!</i>' );
As soon as we have template object we can sync it to a specified scope. E.g. template.sync({ foo: true }); makes
variable foo available for template expressions, template.sync({ foo: { bar: true }}); gets accessable as foo.bar
import { NgTemplate } from "ng-template";
let el = document.querySelector( "#heroForm" ),
elName = document.querySelector( "#name" ),
elPower = document.querySelector( "#power" );
// Bind the template
let template = new NgTemplate( el );
// Set the scope (view state)
let scope = {
powers: [ "-", "Really Smart", "Super Flexible",
"Super Hot", "Weather Changer" ],
power: {
valid: true
},
name: {
valid: true
},
form: {
valid: false
}
};
// Sync to the scope
template.sync( scope );