UNPKG

@danielkalen/simplybind

Version:

Magically simple, framework-less one-way/two-way data binding for frontend/backend in ~5kb.

89 lines (69 loc) 1.75 kB
import {subscriberCollection} from './subscriber-collection'; export class DirtyChecker { constructor() { this.tracked = []; this.checkDelay = 120; } addProperty(property) { let tracked = this.tracked; tracked.push(property); if (tracked.length === 1) { this.scheduleDirtyCheck(); } } removeProperty(property) { let tracked = this.tracked; tracked.splice(tracked.indexOf(property), 1); } scheduleDirtyCheck() { setTimeout(() => this.check(), this.checkDelay); } check() { let tracked = this.tracked; let i = tracked.length; while (i--) { let current = tracked[i]; if (current.isDirty()) { current.call(); } } if (tracked.length) { this.scheduleDirtyCheck(); } } } @subscriberCollection() export class DirtyCheckProperty { constructor(dirtyChecker, obj, propertyName) { this.dirtyChecker = dirtyChecker; this.obj = obj; this.propertyName = propertyName; } getValue() { return this.obj[this.propertyName]; } setValue(newValue) { this.obj[this.propertyName] = newValue; } call() { let oldValue = this.oldValue; let newValue = this.getValue(); this.callSubscribers(newValue, oldValue); this.oldValue = newValue; } isDirty() { return this.oldValue !== this.obj[this.propertyName]; } subscribe(context, callable) { if (!this.hasSubscribers()) { this.oldValue = this.getValue(); this.dirtyChecker.addProperty(this); } this.addSubscriber(context, callable); } unsubscribe(context, callable) { if (this.removeSubscriber(context, callable) && !this.hasSubscribers()) { this.dirtyChecker.removeProperty(this); } } }