UNPKG

can-observable-array

Version:
114 lines (92 loc) 3.2 kB
"use strict"; var canReflect = require("can-reflect"); var mapBindings = require("can-event-queue/map/map"); var canMeta = Symbol.for("can.meta"); var computedPropertyDefinitionSymbol = Symbol.for("can.computedPropertyDefinitions"); var onKeyValueSymbol = Symbol.for("can.onKeyValue"); var offKeyValueSymbol = Symbol.for("can.offKeyValue"); // ## ComputedObjectObservationData // Instances of this are created to wrap the observation. // The `.bind` and `.unbind` methods should be called when the // instance's prop is bound or unbound. function ComputedObjectObservationData(instance, prop, observation) { this.instance = instance; this.prop = prop; this.observation = observation; this.forward = this.forward.bind(this); } ComputedObjectObservationData.prototype.bind = function () { this.bindingCount++; if (this.bindingCount === 1) { this.observation.on(this.forward, "notify"); } }; ComputedObjectObservationData.prototype.unbind = function () { this.bindingCount--; if (this.bindingCount === 0) { this.observation.off(this.forward, "notify"); } }; ComputedObjectObservationData.prototype.forward = function (newValue, oldValue) { mapBindings.dispatch.call(this.instance, { type: this.prop, key: this.prop, target: this.instance, value: newValue, oldValue: oldValue // patches: [{ // key: this.prop, // type: "set", // value: newValue // }] // keyChanged: undefined }, [newValue, oldValue]); }; ComputedObjectObservationData.prototype.bindingCount = 0; function findComputed(instance, key) { var meta = instance[canMeta]; var target = meta.target; var computedPropertyDefinitions = target[computedPropertyDefinitionSymbol]; if (computedPropertyDefinitions === undefined) { return; } var computedPropertyDefinition = computedPropertyDefinitions[key]; if (computedPropertyDefinition === undefined) { return; } if (meta.computedKeys[key] === undefined) { meta.computedKeys[key] = new ComputedObjectObservationData(instance, key, computedPropertyDefinition(instance, key)); } return meta.computedKeys[key]; } var computedHelpers = { bind: function bind(instance, key) { var computedObj = findComputed(instance, key); if (computedObj === undefined) { return; } computedObj.bind(); }, addKeyDependencies: function addKeyDependencies(proxyKeys) { var onKeyValue = proxyKeys[onKeyValueSymbol]; var offKeyValue = proxyKeys[offKeyValueSymbol]; canReflect.assignSymbols(proxyKeys, { "can.onKeyValue": function canOnKeyValue(key) { computedHelpers.bind(this, key); return onKeyValue.apply(this, arguments); }, "can.offKeyValue": function canOffKeyValue(key) { computedHelpers.unbind(this, key); return offKeyValue.apply(this, arguments); }, "can.getKeyDependencies": function canGetKeyDependencies(key) { var computedObj = findComputed(this, key); if (computedObj === undefined) { return; } return { valueDependencies: new Set([computedObj.observation]) }; } }); } }; module.exports = computedHelpers;