From 6417a3e9eb7ab0011cefada8db855aa929a64ff8 Mon Sep 17 00:00:00 2001 From: Peter Bacon Darwin Date: Thu, 25 Sep 2014 21:06:07 +0100 Subject: [PATCH] feat(Scope): allow the parent of a new scope to be specified on creation This enables us to place transclude scopes more accurately in the scope hierarchy. --- src/ng/rootScope.js | 22 +++++++++++++++------- test/ng/rootScopeSpec.js | 9 +++++++++ 2 files changed, 24 insertions(+), 7 deletions(-) diff --git a/src/ng/rootScope.js b/src/ng/rootScope.js index 34e69b1bd325..15eabf7a8896 100644 --- a/src/ng/rootScope.js +++ b/src/ng/rootScope.js @@ -184,12 +184,20 @@ function $RootScopeProvider(){ * When creating widgets, it is useful for the widget to not accidentally read parent * state. * + * @param {Scope} [parent=this] The {@link ng.$rootScope.Scope `Scope`} that will be the `$parent` + * of the newly created scope. Defaults to `this` scope if not provided. + * This is used when creating a transclude scope to correctly place it + * in the scope hierarchy while maintaining the correct prototypical + * inheritance. + * * @returns {Object} The newly created child scope. * */ - $new: function(isolate) { + $new: function(isolate, parent) { var child; + parent = parent || this; + if (isolate) { child = new Scope(); child.$root = this.$root; @@ -213,13 +221,13 @@ function $RootScopeProvider(){ child = new this.$$ChildScope(); } child['this'] = child; - child.$parent = this; - child.$$prevSibling = this.$$childTail; - if (this.$$childHead) { - this.$$childTail.$$nextSibling = child; - this.$$childTail = child; + child.$parent = parent; + child.$$prevSibling = parent.$$childTail; + if (parent.$$childHead) { + parent.$$childTail.$$nextSibling = child; + parent.$$childTail = child; } else { - this.$$childHead = this.$$childTail = child; + parent.$$childHead = parent.$$childTail = child; } return child; }, diff --git a/test/ng/rootScopeSpec.js b/test/ng/rootScopeSpec.js index e3168ec10e86..1331a97f7d20 100644 --- a/test/ng/rootScopeSpec.js +++ b/test/ng/rootScopeSpec.js @@ -72,6 +72,15 @@ describe('Scope', function() { expect(child.$new).toBe($rootScope.$new); expect(child.$root).toBe($rootScope); })); + + it("should attach the child scope to a specified parent", inject(function($rootScope) { + var isolated = $rootScope.$new(true); + var trans = $rootScope.$new(false, isolated); + $rootScope.a = 123; + expect(isolated.a).toBeUndefined(); + expect(trans.a).toEqual(123); + expect(trans.$parent).toBe(isolated); + })); });