Skip to content
Permalink
Browse files

dynamic binding with ractive.js

  • Loading branch information
crocuis committed May 25, 2016
1 parent 69f26fc commit 57c7a32a618b308dd89fc71a4e4c9702ac554823
Showing with 16,808 additions and 0 deletions.
  1. +3 −0 Examples/Content/HelloRactive.umap
  2. +186 −0 Examples/Content/Scripts/helloRactive.js
  3. +16,619 −0 Examples/Content/Scripts/ractive.js
Git LFS file not shown
@@ -0,0 +1,186 @@
/// <reference path="typings/ue.d.ts">/>
// ; typing info for auto-completion in Visual Studio Code
let UMG = require('UMG')
let instantiator = require('instantiator')
let _ = require('lodash')

function GetPC() {
return PlayerController.C(GWorld.GetAllActorsOfClass(PlayerController).OutActors[0])
}

(function (global) {
"use strict"

function dyn_wrap(ractive,prop,bindings,design) {
let elem
let observe
function update(value) {
let bag = {}
_.each(bindings,(v,k) => {
bag[k] = _.get(v(value), prop)
})
elem.set_attrs(bag)
}
function listener(cur, prev, keyPath) {
update(ractive.get())
}
function link() {
observe = ractive.observe(prop, listener)
}
function unlink() {
observe.cancel()
}

let old = design.$link
design.$link = _elem => {
elem = _elem
old && old()
update(ractive)
link()
}
let old_unlink = design.$unlink
design.$unlink = _ => {
old_unlink && old_unlink()
unlink()
}
return design
}

function dyn_object(ractive, prop, fn) {
let elem
let observe
let old = _.clone(ractive.get(prop))

function update(data) {
elem.remove_children()
let widget = fn(data)
if(widget) {
elem.add_child(widget)
}
}

function listener(cur, prev, keyPath) {
if(ractive.get(prop) != old) {
update(ractive.get(prop))
}
old = _.clone(ractive.get(prop))
}
function link(_elem) {
elem = _elem
update(ractive.get(prop))
observe = ractive.observe(prop, listener)
}
function unlink() {
observe.cancel()
}
return UMG.div({$link:link,$unlink:unlink})

}

function dyn_array(ractive,array,prop,fn) {
let elem
let observe
let map = new Map()

let old = [...ractive.get(array)]
function add(added) {
added.forEach(x => {
let data = _.get(x, prop)
map.set(data,elem.add_child(fn(data)))
})
}
function remove(removed) {
removed.forEach(x => {
let data = _.get(x, prop)
elem.remove_child(map.get(data))
map.delete(x)
})
}
function listener(cur, prev, keyPath) {
let added = _.difference(ractive.get(array),old)
let removed = _.difference(old,ractive.get(array))
old = [...ractive.get(array)]
add(added)
remove(removed)
}
function link(_elem) {
elem = _elem
add(ractive.get(array))
observe = ractive.observe(array, listener)
}
function unlink() {
observe.cancel()
}
return UMG.div({$link:link,$unlink:unlink})
}


function main() {
let content = {hello: 'hello'}
let people = [
{name: 'Rich Harris'},
{name: 'Marty Nelson'}
]
let obj = { a: { b: { c: 1 } } };

let ractive = new Ractive({
data : {
content: content,
people: people,
obj : obj
}})

let PC = GetPC()

let design = UMG.div({},
dyn_object(ractive, 'content.hello', x => {
return UMG.text({}, `${x}`)
}),
dyn_array(ractive, 'people', 'name', x => {
return UMG.text({}, `${x}`)
}, UMG.span({})),
dyn_wrap(ractive, 'obj.a.b.c', {Text:x => x}, UMG.text({}, ""))
)
let i = 0
let j = 100

function tick() {
people.push({name: `h ${i++}`})
people.splice(0, 1)
obj.a.b.c = `${j--}`
content.hello += `${i}`
ractive.update('content.hello')
ractive.update('obj.a.b.c')
setTimeout(__ => tick(), 1000)
}
setTimeout(__ => tick(), 1000)

let page = instantiator(design)

let widget = GWorld.CreateWidget(JavascriptWidget, PC)

widget.SetRootWidget(page)
widget.AddToViewport()

// clean up the mess
return function () {
widget.RemoveFromViewport()
}
}

// bootstrap to initiate live-reloading dev env.
try {
module.exports = () => {
let cleanup = null

// wait for map to be loaded.
process.nextTick(() => cleanup = main());

// live-reloadable function should return its cleanup function
return () => cleanup()
}
}
catch (e) {
require('bootstrap')('helloRactive')
}
})(this)

0 comments on commit 57c7a32

Please sign in to comment.
You can’t perform that action at this time.