Two-Way BindingLoading saved progress…

Two-Way Binding

Angular's [(ngModel)], Vue's v-model, and Svelte's bind:value all sell the same trick: a form field and a piece of state stay glued together. Type in the box and the model updates; change the model in code and the box updates. It looks like magic, but it's two one-way bindings wired back to back — a DOM event going one way, a property setter going the other.

Implement twoWayBinding(input, model, key). Sync input.value with model[key] in both directions, and return an unbind() that tears the binding down.

Signature

function twoWayBinding(input, model, key) {
  // returns unbind(): removes the listener and restores model[key] as plain data
}

Examples

const input = document.createElement('input');
const model = { name: 'ada' };
const unbind = twoWayBinding(input, model, 'name');

input.value;                     // 'ada'  (initial sync)
input.value = 'grace';
input.dispatchEvent(new Event('input'));
model.name;                      // 'grace' (DOM -> model)

model.name = 'lin';
input.value;                     // 'lin'   (model -> DOM)

unbind();                        // stop syncing

Notes

  • DOM → model — listen for the input event and copy input.value into the backing store.
  • model → DOM — a plain object can't tell you when it's assigned, so redefine model[key] as an accessor (Object.defineProperty get/set) whose setter writes to input.value.
  • Keep it enumerable — the key should still show up in Object.keys(model) and behave like a normal property to readers.
  • Clean teardownunbind() removes the event listener and turns model[key] back into a plain data property holding the last value.
Loading editor…