Is it possilbe to introspect/reflect of the model in Angular app, where you can change the scope and traverse it? Something like batarang have but that will allow to change the values.
If not is it possilbe to monkey patch Angular code (by including another script on the page) that will make it possilbe?
1. Accessing/Modyfing scope properties
Angular's $scope objects are plain old JS objects, so thay can be manipulated the standard way.
E.g. someScope.someProp retrieves the value of a property, while someScope.someProp = someValue sets the value of a property.
2. Letting Angular know
Modifying the object's properties is one thing - making Angular aware of the change is another.
Angular will not know about our modifications, until it runs a $digest cycle. If we want to apply the changes right away, we can explicitely trigger a $digest cycle, by using someScope.$apply().
3. Getting hold of a scope
In order to get a reference to the scope associated with a DOM element, we need to have a reference to the corresponding DOM Node object, wrap it in angular.element and execute its scope() method.
Something like this:
<body class="ng-scope">
var someScope = angular.element(document.body).scope();
Furthermore, if we want to access the $rootScope (the parent scope of all scopes), we can use the injector to inject the $rootScope service:
<html ng-app="myApp">
var injector = angular.element(document.documentElement).injector();
var rootScope = injector.get('$rootScope');
4. Traversing the scope-tree
Once we get hold of a scope object, we might want to traverse the scope-tree. Every scope has the following properties (among others):
$parent: The parent scope of this scope (if any).$$nextSibling: The next sibling scope of this scope (if any).$parent)$$childHead: The first child scope of this scope (if any).In order to traverse the branch of the scope-tree with someScope as its root:
var scopes = [someScope];
while (scopes.length) {
var scope = scopes.shift();
console.log(scope);
if (scope.$$nextSibling) { scopes.unshift(scope.$$nextSibling); }
if (scope.$$childHead) { scopes.unshift(scope.$$childHead); }
}
E.g. to traverse the whole scope-tree, you can use the following snippet:
var injector = angular.element(document.body).injector();
var rootScope = injector.get('$rootScope');
var scopes = [rootScope];
while (scopes.length) {
var scope = scopes.shift();
report(scope);
if (scope.$$nextSibling) { scopes.unshift(scope.$$nextSibling); }
if (scope.$$childHead) { scopes.unshift(scope.$$childHead); }
}
function report(scope) {
var str = '' + scope.$id;
while (scope.$parent) {
str = scope.$parent.$id + ' => ' + str;
scope = scope.$parent;
}
console.log(str);
}
Found the way, here is a code that change the scope outside of Angular:
var $scope = angular.element($('.section:eq(0)')).scope();
$scope.$apply(function() {
scope.color = "blue";
});
the angular.element().scope() will return scope and can be investigated. Not sure about how to traverse scope tree, but this is good starting point. If there is no scope traverse you could just traverse the DOM and check if there is new scope on that DOM element.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With