aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/Scope.js28
-rw-r--r--test/ScopeSpec.js34
2 files changed, 57 insertions, 5 deletions
diff --git a/src/Scope.js b/src/Scope.js
index 75a33813..1f8e81e5 100644
--- a/src/Scope.js
+++ b/src/Scope.js
@@ -165,14 +165,31 @@ function createScope(parent, providers, instanceCache) {
}
},
- $watch: function(watchExp, listener, exceptionHandler) {
+
+ /**
+ * Registers `listener` as a watcher of the `watchExp` and executes it (optional, see `initRun`
+ * flag). Afterwards `listener` is executed every time the result of `watchExp` changes.
+ *
+ * The `listener` function will be called with two parameters `newValue` and `oldValue`.
+ *
+ * @param {Function|string} watchExp Expression that yields results. Can be an angular string
+ * expression or a function.
+ * @param {Function|string} listener Function (or angular string expression) that gets called
+ * every time the value of the `watchExp` changes.
+ * @param {Function} exceptionHanlder Handler that gets called when listeners throws an
+ * exception.
+ * @param {boolean} [initRun=true] Flag that prevents the first execution of the listener upon
+ * registration.
+ */
+ $watch: function(watchExp, listener, exceptionHandler, initRun) {
var watch = expressionCompile(watchExp),
- last = {};
+ last = watch.call(instance);
listener = expressionCompile(listener);
- function watcher(){
+ function watcher(firstRun){
var value = watch.call(instance),
+ // we have to save the value because listener can call ourselves => inf loop
lastValue = last;
- if (last !== value) {
+ if (firstRun || lastValue !== value) {
last = value;
instance.$tryEval(function(){
return listener.call(instance, value, lastValue);
@@ -180,7 +197,8 @@ function createScope(parent, providers, instanceCache) {
}
}
instance.$onEval(PRIORITY_WATCH, watcher);
- watcher();
+ if (isUndefined(initRun)) initRun = true;
+ if (initRun) watcher(true);
},
$onEval: function(priority, expr, exceptionHandler){
diff --git a/test/ScopeSpec.js b/test/ScopeSpec.js
index 4a207bf0..8b4ada5a 100644
--- a/test/ScopeSpec.js
+++ b/test/ScopeSpec.js
@@ -96,6 +96,40 @@ describe('scope/model', function(){
model.$eval();
expect(count).toEqual(1);
});
+
+ it('should run listener upon registration by default', function() {
+ var model = createScope();
+ var count = 0,
+ nameNewVal = 'crazy val 1',
+ nameOldVal = 'crazy val 2';
+
+ model.$watch('name', function(newVal, oldVal){
+ count ++;
+ nameNewVal = newVal;
+ nameOldVal = oldVal
+ });
+
+ expect(count).toBe(1);
+ expect(nameNewVal).not.toBeDefined();
+ expect(nameOldVal).not.toBeDefined();
+ });
+
+ it('should not run listener upon registration if flag is passed in', function() {
+ var model = createScope();
+ var count = 0,
+ nameNewVal = 'crazy val 1',
+ nameOldVal = 'crazy val 2';
+
+ model.$watch('name', function(newVal, oldVal){
+ count ++;
+ nameNewVal = newVal;
+ nameOldVal = oldVal
+ }, undefined, false);
+
+ expect(count).toBe(0);
+ expect(nameNewVal).toBe('crazy val 1');
+ expect(nameOldVal).toBe('crazy val 2')
+ });
});
describe('$bind', function(){