diff options
| author | Igor Minar | 2010-11-11 16:21:51 -0800 | 
|---|---|---|
| committer | Igor Minar | 2010-11-11 16:39:01 -0800 | 
| commit | 0a8b3161b19c115ac3854217801e56ae766ab399 (patch) | |
| tree | 3a64c0530098dc16a0164c9502134accfed3cbcd | |
| parent | ba554eeb1bb6a6fc12307d33a5becd8b8ecd6cd7 (diff) | |
| download | angular.js-0a8b3161b19c115ac3854217801e56ae766ab399.tar.bz2 | |
$watch should optionally skip listener exec
- if initRun param is set to false, listener doesn't execute
- the oldValue should equal newValue during the initial execution
- added docs
- added specs
| -rw-r--r-- | src/Scope.js | 28 | ||||
| -rw-r--r-- | test/ScopeSpec.js | 34 | 
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(){  | 
