interbind v0.1.0
interbind
A binding and event library useful for implementing the MVC pattern for JavaScript/TypeScript.
WARNING: This library is in early stages of development. Breaking API changes are expected to happen. See the GitHub issues for more information.
Binding
Binding is the process of establishing a connection between two properties. They are an event-based data flow abstraction managed by the BindingService class and its exposed decorators.
NOTE: The behaviour and function of bindings are similar to data binding in WPF.
Bindings are made up of two components:
- A
bindable, which is the source property in the binding relation. It can have multiple properties targeting it as their source. - A
boundwhich is a replica of the bindable property it targets.
Additionally, each binding has a number of optional arguments to configure its behaviour. These include:
- the mode with which to bind properties.
- One-way binding causes changes to the
bindableproperty to automatically update theboundproperty, but changes targeting theboundproperty are not propegated back to thebindableproperty. - Two-way binding causes changes to either the
bindableproperty or theboundproperty to automatically update the other.
- One-way binding causes changes to the
- the action which allows the class of the
boundproperty to respond to changes (e.g. refresing a view). - the transform to use on the
bindabledata when updating theboundproperty. (Only available on one-way bindings.)
Usage
Import the binding components of the library you would like to use.
import { /* BindingService, Bindable, Bind, etc. */ } from "interbind";bindable
A bindable can be created in the following ways:
- declaratively using a TypeScript decorator:
class Source {
@Bindable
public text?: string;
}- imperatively using the
BindingServiceclass: NOTE: The imperative definition of binding components is subject to change in the very near future.
class Source {
public text?: string;
constructor() {
BindingService.markBindable(this, "text", String);
BindingService.makeBindable(this, "text");
}
}bound
A bound can be created similarly, using either a declarative or imperative syntax. For example, a binding to an instance of the previously defined bindable would look like this:
- delaratively using the TypeScript decorator:
NOTE: The use of the
BindingService.init()call is mandatory to initialize allboundproperties declared using decorators. (Static properties reside on their class and thus have to be initialised seperately from instanced properties.)
let src: Source = new Source();
class Replica {
@Bind(src, "text")
public text?: string;
constructor() {
BindingService.init(this);
}
}- imperatively using the
BindingServiceclass:
let src: Source = new Source();
class Replica {
public text?: string;
constructor() {
BindingService.bind(this, "text", src, "text");
}
}Example
Here is an example for use with a React component (and corresponding backing store):
import { BindingService, Bindable, Bind, ReactBind } from "interbind";
BindingService.defaultBindAction = ReactBind;
public class User {
public username: string;
}
public abstract class UserManager {
@Bindable
public static currentUser: User;
}
public class Navigation extends React.Component<any, any> {
@Bind(UserManager, "currentUser")
private user: User;
componentDidMount() {
BindingService.init(this);
}
render() {
return (
<div>{this.user ? this.user.username : "login"}</div>
)
}
}7 years ago