Reactive-lite

Simplified yet powerful reactive component

View project on GitHub

Demo

Basic text-interpolationt

User name is {first} {last}, works at {company}

<div>User name is {first} {last}, works at {company}</div>
          

text interpolation by function

Tags: {showTags()}

<div>Tags: <code>{showTags()}</code></div>
          

text interpolation with build in filter

Balance with decimal: {balance | currency true}

<div>Balance with decimal: {balance | currency true}</div>
          

attribute interpolation

picture

Feed back at {email}


<img data-src="{picture}" alt="picture"/>
<p>Feed back at <a data-href="mailto:{email}?subject=feedback">{email}</a></p>
            

data-html


<p> data-html="about"></p>
            

data-render


<div data-render="renderCounter"></div>
            

renderCounter: function (model, node) {
  if (!this.counter) {
    var counter = this.counter = new Counter
    node.appendChild(counter.el)
    counter.digits(5)
    counter.update(model.balance)
  } else {
    this.counter.update(model.balance)
  }
}
            

event handler

{address}

<div><input type="text" name="address" on-input="update" data-value="{address}"/></div>
            

update: function (e, model, node) {
  var attr = node.getAttribute('name')
  var val = node.value
  if (attr in model) {
    model[attr] = val
  }
}
            

Custom binding


<div><span moment="registered" format="MMM Do YY"></span></div>
            

moment: function (attr) {
  this.bind(attr, function (model, node) {
    var format = node.getAttribute('format')
    node.textContent = moment(model[attr]).format(format)
  })
}
            

Custom filter

Longitude: {longitude | integer}, latitude: {latitude | integer}

<div> Longitude: {longitude | integer}, latitude: {latitude | integer} </div>
          

integer: function (val) {
  if (!val) return 0
  return parseInt(val, 10)
}
          

Javascript code


var User = Model('User')
var user = new User(attrs)
user.showTags = function () {
  return this.tags.join(',')
}
var delegate = {
  update: function (e, model, node) {
    var attr = node.getAttribute('name')
    var val = node.value
    if (attr in model) {
      model[attr] = val
    }
  },
  renderCounter: function (model, node) {
    if (!this.counter) {
      var counter = this.counter = new Counter
      node.appendChild(counter.el)
      counter.digits(5)
      counter.update(model.balance)
    } else {
      this.counter.update(model.balance)
    }
  }
}
var bindings = {
  moment: function (attr) {
    this.bind(attr, function (model, node) {
      var format = node.getAttribute('format')
      node.textContent = moment(model[attr]).format(format)
    })
  }
}

var filters = {
  integer: function (val) {
    if (!val) return 0
    return parseInt(val, 10)
  }
}
var el = document.getElementById('user')
Reactive(el, user, {
  delegate: delegate,
  bindings: bindings,
  filters: filters
})