I would like to know how to get a list of all child scopes given a parent scope. All I can find from the properties of the scope are $$childHead, $$childTail, $$nextSibling and $$prevSibling.
The approach I'm using now is to get the childHead from the parent and then using the nextSibling to get the next child until nextSibling is null.
Is there a better approach?
Given that I want to call a method [getModel] on all the children, is there again a better way of doing this?
The child directives are using isolated scopes and at such have their own values which are not visible from the parent. I want to access these values from the parent scope.
The 'Angular way' to deal with the issue of "parent scopes needing access to child scopes" is to move the model up into the parent, and have the child scopes reference the parent properties/data (rather than the child scopes having their own local properties/copies). E.g., this is how we deal with ng-repeat if each iteration contains, say, an input form element (i.e., each iteration needs two-way databinding): Difficulty with ng-model, ng-repeat, and inputs
With directives, first define an array of objects in the parent scope, then have each isolated child scope access that parent scope array (or individual object) using the '=' notation (i.e., two-way databinding notation). Because an object is being shared, the isolated scopes will reference the parent objects (they will not get a local copy). Now, any changes you make to the child scopes properties are actually changing the parent scope properties.
All Angular scope are attached to DOM element, you can start by inspecting child using the current element down to whatever child you want to reach. Once there, use below function to get the scope.
angular.element('#5th_element').scope();
In AngularJS 1.3.2, a countChildScopes
method was added to the ngMock module:
/**
* @ngdoc method
* @name $rootScope.Scope#$countChildScopes
* @module ngMock
* @description
* Counts all the direct and indirect child scopes of the current scope.
*
* The current scope is excluded from the count. The count includes all isolate child scopes.
*
* @returns {number} Total number of child scopes.
*/
function countChildScopes(scope)
{
// jshint validthis: true
var count = 0; // exclude the current scope
var root = scope || angular.element(document).injector().get('$rootScope');
var pendingChildHeads = [root.$$childHead];
var currentScope;
while (pendingChildHeads.length)
{
currentScope = pendingChildHeads.shift();
while (currentScope)
{
count += 1;
pendingChildHeads.push(currentScope.$$childHead);
currentScope = currentScope.$$nextSibling;
}
}
return count;
}
Use an object as a return value to get the IDs:
function enumerateChildScopes(scope)
{
// jshint validthis: true
var enum = {}; // exclude the current scope
var root = scope || angular.element(document).injector().get('$rootScope');
var pendingChildHeads = [root.$$childHead];
var currentScope;
while (pendingChildHeads.length)
{
currentScope = pendingChildHeads.shift();
while (currentScope)
{
enum["scope"+pendingChildHeads.length] = currentScope.$id;
pendingChildHeads.push(currentScope.$$childHead);
currentScope = currentScope.$$nextSibling;
}
}
return enum;
}
References