AngularJS access scope from outside js function

I'm trying to see if there's a simple way to access the internal scope of a controller through an external javascript function (completely irrelevant to the target controller)

I've seen on a couple of other questions here that

angular.element("#scope").scope();

would retrieve the scope from a DOM element, but my attempts are currently yielding no proper results.

Here's the jsfiddle: http://jsfiddle.net/sXkjc/5/

I'm currently going through a transition from plain JS to Angular. The main reason I'm trying to achieve this is to keep my original library code intact as much as possible; saving the need for me to add each function to the controller.

Any ideas on how I could go about achieving this? Comments on the above fiddle are also welcome.


Solution 1:

You need to use $scope.$apply() if you want to make any changes to a scope value from outside the control of angularjs like a jquery/javascript event handler.

function change() {
    alert("a");
    var scope = angular.element($("#outer")).scope();
    scope.$apply(function(){
        scope.msg = 'Superhero';
    })
}

Demo: Fiddle

Solution 2:

It's been a while since I posted this question, but considering the views this still seems to get, here's another solution I've come upon during these last few months:

$scope.safeApply = function( fn ) {
    var phase = this.$root.$$phase;
    if(phase == '$apply' || phase == '$digest') {
        if(fn) {
            fn();
        }
    } else {
        this.$apply(fn);
    }
};

The above code basically creates a function called safeApply that calles the $apply function (as stated in Arun's answer) if and only Angular currently isn't going through the $digest stage. On the other hand, if Angular is currently digesting things, it will just execute the function as it is, since that will be enough to signal to Angular to make the changes.

Numerous errors occur when trying to use the $apply function while AngularJs is currently in its $digest stage. The safeApply code above is a safe wrapper to prevent such errors.

(note: I personally like to chuck in safeApply as a function of $rootScope for convenience purposes)

Example:

function change() {
    alert("a");
    var scope = angular.element($("#outer")).scope();
    scope.safeApply(function(){
        scope.msg = 'Superhero';
    })
}

Demo: http://jsfiddle.net/sXkjc/227/

Solution 3:

Another way to do that is:

var extScope;
var app = angular.module('myApp', []);
app.controller('myController',function($scope, $http){
    extScope = $scope;
})
//below you do what you want to do with $scope as extScope
extScope.$apply(function(){
    extScope.test = 'Hello world';
})