All Projects → finom → defi

finom / defi

Licence: MIT license
A bunch of utilities that enable accessor-based reactivity for JavaScript objects

Programming Languages

javascript
184084 projects - #8 most used programming language
shell
77523 projects
typescript
32286 projects
HTML
75241 projects

Projects that are alternatives of or similar to defi

awesome-callbags
Callbag Libraries & Learning Material https://github.com/callbag/callbag
Stars: ✭ 85 (+77.08%)
Mutual labels:  reactive-programming
sample-spring-reactive
sample reactive microservices using spring 5, spring boot, spring webflux and project reactor
Stars: ✭ 26 (-45.83%)
Mutual labels:  reactive-programming
bound
Data-binding made easy
Stars: ✭ 21 (-56.25%)
Mutual labels:  two-way-data-binding
cycle-hn
Hackernews Clone Using CycleJS
Stars: ✭ 42 (-12.5%)
Mutual labels:  reactive-programming
servable
"simple" observable implementation based off RxJS & kefir Docs
Stars: ✭ 14 (-70.83%)
Mutual labels:  reactive-programming
Combine
🐻‍❄️ Combine 을 공부해 봅시다 🐧
Stars: ✭ 24 (-50%)
Mutual labels:  reactive-programming
ObservableComputations
Cross-platform .NET library for computations whose arguments and results are objects that implement INotifyPropertyChanged and INotifyCollectionChanged (ObservableCollection) interfaces.
Stars: ✭ 94 (+95.83%)
Mutual labels:  reactive-programming
mongo-images
Ever wonder how you can create a full stack reactive application that also saves images? Well look no further! We've got Spring Webflux, Reactive Mongo Streams with GridFS, and Angular5!
Stars: ✭ 12 (-75%)
Mutual labels:  reactive-programming
springboot2-swagger
Swagger integration with Spring Boot 2.0.1.BUILD-SNAPSHOT and Spring Cloud Finchley.BUILD-SNAPSHOT
Stars: ✭ 17 (-64.58%)
Mutual labels:  reactive-programming
RetrofitRxErrorHandler
Hardening Retrofit RxJaxa API Layer against random errors
Stars: ✭ 15 (-68.75%)
Mutual labels:  reactive-programming
netifi-quickstart-java
Project to assist you in getting started using Netifi.
Stars: ✭ 23 (-52.08%)
Mutual labels:  reactive-programming
realar
5 kB Advanced state manager for React
Stars: ✭ 41 (-14.58%)
Mutual labels:  reactive-programming
SyncedStore
SyncedStore CRDT is an easy-to-use library for building live, collaborative applications that sync automatically.
Stars: ✭ 1,053 (+2093.75%)
Mutual labels:  reactive-programming
node-casperjs-aws-lambda
Base scaffolding app for a casperjs/phantomjs app running on Amazon (AWS) Lambda
Stars: ✭ 52 (+8.33%)
Mutual labels:  reactive-programming
most-behave
Experimental continuous Behaviors for most.js
Stars: ✭ 32 (-33.33%)
Mutual labels:  reactive-programming
reactive-angular-workshop
This is the source code for the world's greatest Reactive Angular Workshop.
Stars: ✭ 30 (-37.5%)
Mutual labels:  reactive-programming
makinage
Stream Processing Made Easy
Stars: ✭ 31 (-35.42%)
Mutual labels:  reactive-programming
WhatFilm
Simple iOS app using TMDb API and RxSwift
Stars: ✭ 35 (-27.08%)
Mutual labels:  reactive-programming
learnrx-zh-cn
ReactiveX 官方互动式教程中文翻译,原仓库 https://github.com/ReactiveX/learnrx
Stars: ✭ 52 (+8.33%)
Mutual labels:  reactive-programming
DARK
Dagger 2 + Anko + Rx + Kotlin
Stars: ✭ 27 (-43.75%)
Mutual labels:  reactive-programming

Data binding without framework: a bunch of utilities that enable accessor-based reactivity for JavaScript objects.

npm version Coverage Status

If you're looking for defi-react get its README here.

It can be installed via NPM:

npm i defi
const { bindNode, calc } = require('defi');

bindNode(obj, 'key', node)

Or downloaded to use as a global variable

// use defi as a global variable
defi.bindNode(obj, 'key', node)

How would I use it?

Skip this section if you're using defi-react because React handles DOM rendering by its own.

As a simple task let's say you want to define a simple form with first name and last name input, where while you type a greeting appears.

<input class="first">
<input class="last">
<output class="greeting"></output>
// default data
const obj = {
  first: 'John',
  last: 'Doe'
};

// let's listen for first and last name changes
defi.on(obj, 'change:first', () => console.log('First name is changed'));
defi.on(obj, 'change:last', () => console.log('Last name is changed'));

// we would like to re-calculate 'greeting' property every time
// when the first or last are changed
defi.calc(obj, 'greeting', ['first', 'last'], (first, last) => `Hello, ${first} ${last}`);

// and we want to set up a two-way data binding between the props
// and corresponding DOM nodes
defi.bindNode(obj, {
  first: '.first',
  last: '.last',
  greeting: '.greeting'
});

If first or last is changed then event handlers print info about that to console, greeting property is updated, .greeting element is populated by calculated data (by default "Hello, John Doe"). And it happens every time when these properties are changed and it doesn't matter which way. You can do obj.first = 'Jane' or you can type text into its field, and everything will happen immediately.

That's the real accessor-based reactiveness! Check the example above here and try to type obj.first = 'Jane' at the "Console" tab.

Note that if you want to use a custom HTML element (at the example above we use <output> tag) to update its innerHTML you will need to pass so-called "binder" as a rule of how the bound element should behave. By default defi.bindNode doesn't know how to interact with non-form elements.

const htmlBinder = {
  setValue: (value, binding) => binding.node.innerHTML = value,
};
// this will update innerHTML for any element when obj.greeting is changed
defi.bindNode(obj, 'greeting', '.greeting', htmlBinder)

Also you can use html from common-binders (a collection of binders of general purpose).

const { html } = require('common-binders');
defi.bindNode(obj, 'greeting', '.greeting', html())

Note that there is also a routing library for defi.js - defi-router.

Quick API ref

Full reference with all variations, flags and tutorials live at defi.js.org.

  • bindNode - Binds a property of an object to HTML node, implementing two-way data binding.
// basic use (for standard HTML5 elements)
defi.bindNode(obj, 'myKey', '.my-element');

// custom use (for any custom element)
defi.bindNode(obj, 'myKey', '.my-element', {
    // when is element state changed?
    // (that's a DOM event; a function can be used to listen to any non-DOM events)
    on: 'click',
    // how to extract element state?
    getValue: ({ node }) => someLibraryGetValue(node),
    // how to set element state?
    setValue: (v, { node }) => someLibrarySetValue(node, v),
    // how to initialize the widget?
    // it can be initialized in any way,
    // but 'initialize' function provides some syntactic sugar
    initialize: ({ node }) => someLibraryInit(node),
});

obj.myKey = 'some value'; // updates the element
  • calc - Creates a dependency of one property value on values of other properties (including other objects).
defi.calc(obj, 'a', ['b', 'c'], (b, c) => b + c);
obj.b = 1;
obj.c = 2;
console.log(obj.a); // 3
  • mediate - Transforms property value on its changing.
defi.mediate(obj, 'x', value => String(value));

obj.x = 1;

console.log(obj.x); // "1"
console.log(typeof obj.x); // "string"
  • on - Adds an event handler. Detailed information about all possible events you can get at the "Events" section of the website.
defi.on(obj, 'change:x', () => {
	alert(`obj.x now equals ${obj.x}`);
});

obj.x = 1;
  • off - Deletes an event handler.
defi.off(obj, ['change:x', 'bind']);
defi.on(obj, ['foo', 'bar'], (a, b, c) => {
	alert(a + b + c);
});
defi.trigger(obj, 'foo', 1, 2, 3); // alerts 6
defi.bindNode(obj, 'myKey', '.my-element');

defi.unbindNode(obj, 'myKey', '.my-element');
  • bound - Returns a bound element.
defi.bindNode(obj, 'myKey', '.my-element');
const node = defi.bound(obj, 'myKey'); // will return document.querySelector('.my-element')
  • chain - Allows chained calls of defi.js functions.
defi.chain(obj)
    .calc('a', 'b', b => b * 2)
    .set('b', 3)
    .bindNode('c', '.node');
  • defaultBinders - An array of functions which return a corresponding binder or a falsy value. This makes bindNode to detect how to bind a node if the binder argument isn't given.
defi.defaultBinders.unshift(element => {
	// check if the element has "foo" class name
	if(element.classList.contains('foo')) {
		// if checking is OK, return a new binder
		return {
			on: ...,
			getValue: ...,
			setValue: ...
		};
	}
});

// ...

defi.bindNode(obj, 'myKey', '.foo.bar');
const element = document.createElement('input');
element.type = 'text';

console.log(defi.lookForBinder(element));
  • remove - Deletes a property and removes attached change handlers.
defi.remove(obj, 'myKey');
  • set - Sets a property value allowing to pass an event options object.
defi.set(obj, 'myKey', 3, { silent: true });
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].