Last Updated: September 29, 2021
·
78.57K
· rmcdaniel

Access scope outside of AngularJS

When using AngularJS, it is considered best practice to use AngularJS directives to modify the DOM, not jQuery. Using jQuery a lot usually means that you aren't doing things the "AngularJS way" and is therefore a code smell. But what if you just have to interact directly with AngularJS using jQuery? Here's how.

First, let's create a simple AngularJS application:

<script>
var app = angular.module('app', []);

app.controller('ctrl', ['$scope', function ($scope) {
    $scope.message = 'hello';
}]);    
</script>

<div ng-app="app" ng-controller="ctrl">
{{message}}
</div>

This simple AngularJS application will output a blank page except for the word "hello".

The next step is to somehow get the $scope object so we can read from it and modify it. Fortunately, AngularJS provides this feature via the angular.element() extras (angular.element documentation).

We know that the $scope object that we want is attached to the div with attribute ng-controller="ctrl". We use this as the basis for a selector and then pass the string into angular.element(). Below is a function that does this. The getScope() function accepts a single argument, ctrlName, which is the name of the controller, in this case, "ctrl".

function getScope(ctrlName) {
    var sel = 'div[ng-controller="' + ctrlName + '"]';
    return angular.element(sel).scope();
}

The function would be used as so:

var $scope = getScope('ctrl');

Now, the above $scope variable is the exact same one that is inside of the "ctrl" controller. We can do stuff like changing the message from "hello" to "goodbye".

$scope.message = 'goodbye';
$scope.$apply();

We have to call $apply() because $scope is modified outside of the $digest cycle.

Here it is all put together inside of a JSFiddle demo.

7 Responses
Add your response

Wow nice example. Thanks lot

over 1 year ago ·

If u have any aliasing for ur controller....u have to do one change in calling the angular controller methods.
$scope.ctrlAliasName.methodName();

over 1 year ago ·

Turns out this does not work if debugInfoEnabled is set to true since element().scope() relies on the debugInfo

over 1 year ago ·

I'm having the same issue as varanisi_manoj. I want to use the methods on the $scope, but I get the error Object doesn't support property or method 'methodName'. Other than that, this is really helpful.

over 1 year ago ·

I take that back. Methods are on the scope as expected, but somehow this particular one that I'm trying to use isn't loaded into the scope. Weird. Thanks again!

over 1 year ago ·

I'm given 'Cannot read property '$apply' of undefined', can someone please help me?

over 1 year ago ·

THANK YOU Sir :D

over 1 year ago ·