ReactiveWebv0.2.0

Usage guide.

A real example, a clear model, and an explicit lifetime.

A reactive identity

This is the JavaScript used by the first playground preset. Edit and run it in the interactive playground, including its HTML and CSS.

JavaScript
import {defineViewModel,reactiveProperty,WhenAnyValue,CompositeDisposable,DisposeWith} from '@wieslawsoltes/reactiveweb';
import {Bind,OneWayBind,BindCommand} from '@wieslawsoltes/reactiveweb/html';
const Profile=defineViewModel({
 properties:{FirstName:reactiveProperty('Alex'),LastName:reactiveProperty('Morgan')},
 computed:{FullName:{initialValue:'',source:vm=>WhenAnyValue(vm,'FirstName','LastName',(a,b)=>(a+' '+b).trim())}},
 commands:{Save:{kind:'task',canExecute:vm=>WhenAnyValue(vm,'FirstName',name=>!!name.trim()),execute:async vm=>{
  const message='Hello, '+vm.FullName+'. Your next idea starts here.';
  document.querySelector('#message').textContent=message;console.log(message);return message;
 }}}
});
const vm=new Profile(), lifetime=new CompositeDisposable();lifetime.Add(vm);
DisposeWith(Bind(vm,'FirstName',document.querySelector('#first'),'value'),lifetime);
DisposeWith(Bind(vm,'LastName',document.querySelector('#last'),'value'),lifetime);
DisposeWith(OneWayBind(vm,'FullName',document.querySelector('#name'),'textContent'),lifetime);
DisposeWith(BindCommand(vm.Save,document.querySelector('#save')),lifetime);
lifetime.Add(vm.Save.ThrownExceptions.subscribe(error=>console.error(error)));
window.addEventListener('pagehide',()=>lifetime.Dispose());
console.log('Two-way bindings and a computed FullName are live.');
Show the HTML host
HTML
<div class="toolbar"><label>First name <input id="first" value="Alex"></label><label>Last name <input id="last" value="Morgan"></label><button id="save">Create greeting</button></div><div class="panel"><p class="hint">COMPUTED, NOT COPIED</p><h1 id="name"></h1><p>A live view of two reactive properties.</p><output id="message">Edit either field. This view follows the model.</output></div>

How it works

The view follows the model

Define state and derive what the UI needs. Bind the browser to observable values without replacing its native interaction model.

Install rxjs. Use the root entry for view models and /html for DOM bindings. React integration is an optional separate adapter.

Own the lifetime

Collect subscriptions, bindings and owned view models in a CompositeDisposable and dispose it with the view.

The playground replaces its entire isolated frame on each run. In your application, use the framework’s unmount or disposal hook instead. Do not dispose a shared model while another view still owns it.

Read the lifecycle guide →

Know the contract

An independent web MVVM implementation, not exhaustive ReactiveUI behavior across native platforms. The examples run locally without an application server.

Source repositories can contain work newer than the published package. The showcase uses @wieslawsoltes/reactiveweb@0.2.0.

Upstream compatibility documentation ↗
↑ ↓ to explore · Enter to openEsc to close