1

Simple example:

  <body ng-app="testApp">
    <form name="myForm" id='CtrlHost' ng-controller="Ctrl">
        <input type="Button" value="Change Inside Angular" ng-click="ChangeIt()" />
        <input type="Button" value="Change Outside Angular" onclick="OutsideAngularChange()" />
      </form>
  </body>

angular.module('testApp', [])
    .controller('Ctrl', function($scope, MyService) {
        var NewPropValue = 1;
        $scope.ChangeIt = function () {
            alert("scope.changeit called");
              NewPropValue++;
              MyService.SetMyProp(NewPropValue);
        };
        $scope.$watch(MyService.GetMyProp, function (newValue) {
            alert("NewValue from Watch = " + newValue);   
        });
    }).service('MyService', function () {
       var myProp;

        this.GetMyProp = function () {
            return MyProp;
        };

        this.SetMyProp = function (newProp) {
            MyProp = newProp;   
        };
    });

function OutsideAngularChange() {
                  alert("OutsideAngularChange called")
    angular.element(document.getElementById('CtrlHost')).scope().ChangeIt();
}

http://jsfiddle.net/jonnyknowsbest/4umxanpu/

Hit the "Change Inside Angular" button and the scope watch is triggered. Hit the "Change Outside Angular" button and the scope watch is NOT triggered.

Both buttons call the same scope method to update a service property.

How come one works and one does not?

2 Answers 2

1

Try using $scope.$apply() after changing the value.

https://docs.angularjs.org/api/ng/type/$rootScope.Scope#$apply

Sign up to request clarification or add additional context in comments.

2 Comments

is there a way to go the other way trigger external function when scope value changes?
it's $scope.$watch('var', callback)
1

You answered your own question. $watches are only called inside of $digest(). This is the definition of "inside angular". Since your call is made outside of $digest(), or "outside angular", none of the watchers will be evaluated.

You can manually trigger a digest in a number of ways, but

angular.element(document.getElementById('CtrlHost')).scope().ChangeIt();

angular.element(document.getElementById('CtrlHost')).scope().$apply();

is probably the most appropriate here.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.