8

I'd like to be able to update a scope in Angular from a function outside Angular.

E.g., if I have a jQuery plugin which returns a success callback, I'd like to be able to update the scope from that success callback. Every solution I've seen for this involves calling angular.element(selector).scope and then calling $apply on the scope that is returned. However, I've also seen many comments indicating that this doesn't work when debug info is off and thus it isn't recommended, but I haven't seen any alternative solutions.

Does anyone know of a way to update the scope from outside of Angular without using angular.element(selector).scope?

Here is the accepted solution in the post:

"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';
    });
}

Here is a warning that .scope() doesn't work when debug data is off in the post:

"FYI according to the docs using .scope() requires the Debug Data to be enabled but using Debug Data in production is not recommended for speed reasons. The solutions below seem to revolve around scope() – rtpHarry Dec 5 '14 at 15:12 "

I don't see any alternative solution to using .scope() in this post or in other similar posts.

AngularJS access scope from outside js function

Thanks!

Update One possible solution to not using angular.element(selector).scope was I assigned the scope in the controller I was using FirstCtrl to the window object. I injected $window into the FirstCtrl controller and did the following:

$window.FirstCtrlScope = $scope;

Then from jQuery or other javascript I could do:

var scope=window.FirstCtrlScope;
scope.$apply(function () {
      // update the scope
});

Is this a good solution or are there better solutions for updating a scope without using angular.element(selector).scope?

Thanks!

Community
  • 1
  • 1

2 Answers2

1

I think both ways are bad. Design which sets controllers as global variables, or access to scope by html element leads to unmaintainable application with many hidden links.

If you need cooperate with jQuery plugins (or other non-angular code), wrap it into directive with clear API (attributes, bindings and callbacks).

milanlempera
  • 2,203
  • 1
  • 17
  • 21
1

You can assign the scope to a data attribute on the element, then access that. Take a look here where the angular-ui-bootstrap library implemented that approach.

Rob J
  • 6,609
  • 5
  • 28
  • 29