Add computed.unsubscribeAll. Sometimes we want to remove...

...subscribers without removing dependencies.
This commit is contained in:
Timothy Farrell 2017-11-02 08:35:52 -05:00
parent 1e10b27f69
commit e37679c2c9

View File

@ -4,6 +4,7 @@ export function computed(fn, dependencies = [], comparator = eq) {
let isDirty = true; let isDirty = true;
let val; let val;
// Receive dirty flag from parent logic node (dependency). Pass it down.
function _computedDirtyReporter(_, skipPropagation) { function _computedDirtyReporter(_, skipPropagation) {
if (!isDirty) { if (!isDirty) {
isDirty = true; isDirty = true;
@ -17,6 +18,7 @@ export function computed(fn, dependencies = [], comparator = eq) {
const dependentSubscriptions = Array.from(dependencies).map(d => d._d(_computedDirtyReporter)); const dependentSubscriptions = Array.from(dependencies).map(d => d._d(_computedDirtyReporter));
// Compute new value, call subscribers if changed.
const accessor = function _computed() { const accessor = function _computed() {
if (isDirty) { if (isDirty) {
const newVal = fn.apply(null, dependencies.map(runParam)); const newVal = fn.apply(null, dependencies.map(runParam));
@ -29,6 +31,7 @@ export function computed(fn, dependencies = [], comparator = eq) {
return val; return val;
}; };
// Add child nodes to the logic graph (value-based)
accessor.subscribe = fn => { accessor.subscribe = fn => {
subscribers.add(fn); subscribers.add(fn);
return () => { return () => {
@ -37,17 +40,25 @@ export function computed(fn, dependencies = [], comparator = eq) {
}; };
}; };
// Add child nodes to the logic graph (dirty-based)
accessor._d = fn => { accessor._d = fn => {
dependents.add(fn); dependents.add(fn);
return () => dependents.delete(fn); return () => dependents.delete(fn);
}; };
// Remove this node from the logic graph completely
accessor.detach = () => { accessor.detach = () => {
subscribers.clear(); subscribers.clear();
dependents.clear(); dependents.clear();
dependentSubscriptions.forEach(runParam); dependentSubscriptions.forEach(runParam);
}; };
// Remove child nodes from the logic graph
accessor.unsubscribeAll = () => {
subscribers.clear();
dependents.clear();
};
return accessor; return accessor;
} }