diff --git a/src/ng/compile.js b/src/ng/compile.js index 7ff234fe1c33..eff553c6b9b7 100644 --- a/src/ng/compile.js +++ b/src/ng/compile.js @@ -1896,6 +1896,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { case '@': attrs.$observe(attrName, function(value) { isolateBindingContext[scopeName] = value; + isolateScope.$setDirty(); }); attrs.$$observers[attrName].$$scope = scope; if (attrs[attrName]) { @@ -1929,6 +1930,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { if (!compare(parentValue, lastValue)) { // parent changed and it has precedence isolateBindingContext[scopeName] = parentValue; + isolateScope.$setDirty(); } else { // if the parent can be assigned then do so parentSet(scope, parentValue = isolateBindingContext[scopeName]); diff --git a/src/ng/rootScope.js b/src/ng/rootScope.js index d06abfc248b3..30bda79450ca 100644 --- a/src/ng/rootScope.js +++ b/src/ng/rootScope.js @@ -137,6 +137,7 @@ function $RootScopeProvider() { this.$$listeners = {}; this.$$listenerCount = {}; this.$$isolateBindings = null; + this.$$dirty = false; } /** @@ -202,6 +203,7 @@ function $RootScopeProvider() { if (isolate) { child = new Scope(); child.$root = this.$root; + child.$$dirty = true; } else { // Only create a child scope class if somebody asks for one, // but cache it to allow the VM to optimize lookups. @@ -241,6 +243,13 @@ function $RootScopeProvider() { } }, + $setDirty: function() { + if (!this.hasOwnProperty("$$isolateBindings")) + throw 'Must be isolated scope.'; + + this.$$dirty = true; + }, + /** * @ngdoc method * @name $rootScope.Scope#$watch @@ -722,6 +731,7 @@ function $RootScopeProvider() { next, current, target = this, watchLog = [], logIdx, logMsg, asyncTask; + this.$$dirty = true; beginPhase('$digest'); // Check for changes to browser url that happened in sync before the call to $digest @@ -752,7 +762,9 @@ function $RootScopeProvider() { traverseScopesLoop: do { // "traverse the scopes" loop - if ((watchers = current.$$watchers)) { + var skip = current.$$isolateBindings && !current.$$dirty && !current.$$transcluded; + current.$$dirty = false; + if (!skip && (watchers = current.$$watchers)) { // process our watches length = watchers.length; while (length--) { @@ -1031,6 +1043,7 @@ function $RootScopeProvider() { } finally { clearPhase(); try { + this.$$dirty = true; $rootScope.$digest(); } catch (e) { $exceptionHandler(e); @@ -1063,6 +1076,7 @@ function $RootScopeProvider() { function $applyAsyncExpression() { scope.$eval(expr); + scope.$$dirty = true; } },