From c159ee6131dcd20d80f67dd3d31023aa6a7827ae Mon Sep 17 00:00:00 2001 From: Adam Barrett Date: Mon, 6 Feb 2017 01:52:41 -0600 Subject: [PATCH 1/2] Add pushToStack() and popFromStack() methods to allow async Observations When there is no `func` value passed to an Observation, the methods pushToStack() and popFromStack() can be used to make observations outside of the context of a function call. --- can-observation.js | 27 +++++++++++++++++++++++++++ can-observation_test.js | 25 +++++++++++++++++++++++++ 2 files changed, 52 insertions(+) diff --git a/can-observation.js b/can-observation.js index e37bdf7..514bcad 100644 --- a/can-observation.js +++ b/can-observation.js @@ -101,6 +101,11 @@ function Observation(func, context, compute){ this.childDepths = {}; this.ignore = 0; this.needsUpdate= false; + if (!func) { + this.start = function(){ + this.value = {}; // always set a unique value, so there is always an update + }; + } } // ### observationStack @@ -268,6 +273,28 @@ assign(Observation.prototype,{ this.removeEdge(ob); } this.newObserved = {}; + }, + /** + * @function can-observation.prototype.pushToStack pushToStack + * @parent can-observation.prototype prototype + * + * @signature `observation.pushToStack()` + * + * Starts observing all observables in general until `.popFromStack()` is called. + * + */ + pushToStack() { + this.bound = true; + this.oldObserved = this.newObserved || {}; + this.ignore = 0; + this.newObserved = {}; + // Add this function call's observation to the stack + observationStack.push(this); + }, + popFromStack() { + // pops off the observation, and returns it. + observationStack.pop(); + this.updateBindings(); } /** * @property {*} can-observation.prototype.value diff --git a/can-observation_test.js b/can-observation_test.js index ab6443f..09bff74 100644 --- a/can-observation_test.js +++ b/can-observation_test.js @@ -402,3 +402,28 @@ QUnit.test('should throw if can-namespace.Observation is already defined', funct start(); }); }); + +QUnit.test('pushToStack and popToStack allow observing reads outside of a function', function() { + stop(3); + var expected = ['Adam', 'Brian', 'Curtis', 'David']; + var i = 0; + var observable = simpleObservable('Adam'); + var name = simpleCompute(function(){ + return observable.get(); + }); + var observation = new Observation(null, null, function(newVal, oldVal, batchNum){ + var expectedName = expected[i++]; + QUnit.equal(name(), expectedName, 'Name has become '+expectedName+' and callback called'); + start(); + }); + + QUnit.equal(name(), expected[i++], 'Name starts out Adam'); + + observation.pushToStack(); + name(); + observation.popFromStack(); + + observable.set('Brian'); + observable.set('Curtis'); + observable.set('David'); +}); From 6d23e5342a76587edadeb9433116bd94fcd5e708 Mon Sep 17 00:00:00 2001 From: Adam Barrett Date: Mon, 6 Feb 2017 12:34:37 -0600 Subject: [PATCH 2/2] Remove ES6 syntax, move assignValue function outside of Observation constructor --- can-observation.js | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/can-observation.js b/can-observation.js index 514bcad..7a24c97 100644 --- a/can-observation.js +++ b/can-observation.js @@ -1,3 +1,4 @@ +/*jshint -W003 */ // # can-observation - nice // // This module: @@ -90,7 +91,6 @@ var remaining = {updates: 0, notifications: 0}; * me.name = "Ramiya"; // console.logs -> "Hello Ramiya" * ``` */ - function Observation(func, context, compute){ this.newObserved = {}; this.oldObserved = null; @@ -102,12 +102,15 @@ function Observation(func, context, compute){ this.ignore = 0; this.needsUpdate= false; if (!func) { - this.start = function(){ - this.value = {}; // always set a unique value, so there is always an update - }; + this.start = assignUniqueValue; } } + +function assignUniqueValue() { + this.value = {}; +} + // ### observationStack // // This is the stack of all `observation` objects that are the result of @@ -283,7 +286,7 @@ assign(Observation.prototype,{ * Starts observing all observables in general until `.popFromStack()` is called. * */ - pushToStack() { + pushToStack: function() { this.bound = true; this.oldObserved = this.newObserved || {}; this.ignore = 0; @@ -291,7 +294,7 @@ assign(Observation.prototype,{ // Add this function call's observation to the stack observationStack.push(this); }, - popFromStack() { + popFromStack: function() { // pops off the observation, and returns it. observationStack.pop(); this.updateBindings();