0

I have one controller which is nested into another

<div id="divTest" ng-controller="TestCtrl">
    {{test}}
    <div ng-controller="InnerTestCtrl">
        {{innerTest}}
    </div>
</div>

When I tried to change a scope value into an inner controller after 3 seconds it was failed. Could you please explain why and how reach this behavior (I mean that value will be changed, in example from 1 to 2)?

var app = angular.module("TestApp", []);
app.controller("TestCtrl", function($scope)
               {
                   $scope.test = "a";
               });
app.controller("InnerTestCtrl", function($scope)
               {
                   $scope.innerTest = "1";
                   window.setTimeout(function() 
                                     {
                                         $scope.innerTest = "2";
                                     }, 3000);
               });
angular.bootstrap(document.getElementById("divTest"), ["TestApp"]);

example in jsfiddle

3 Answers 3

3

Instead of using window.setTimeout(), use $timeout service because when you are setting the value of $scope.innerTest, it is in the function window.setTimeout(), about which angular has no idea at all. When you change the value of the model inside that function the model will not be updated until you call $scope.$apply() function to make the angular know that some value has changed outside the scope of angular. So, there are two fixes. The first one is:

$scope.innerTest = "2";
 $scope.$apply($scope.innerTest);

the second one is the best approach, which is actually the angular approach:

app.controller("InnerTestCtrl", function($scope, $timeout)
               {
                   $scope.innerTest = "1";
                   $timeout(function() 
                                     {
                                         $scope.innerTest = "2";
                                     }, 3000);
               });

Don't forget to inject the $timeout service. Hope this will make your concept clear about this :)

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

Comments

1

Looks like you should you $scope.$apply(), or inner service $timeout.
I think you need to use $timeout service.

var app = angular.module('TestApp', []);
app.controller('TestCtrl', ['$scope', function($scope) {
    $scope.test = 'a';
}]);
app.controller('InnerTestCtrl', ['$scope', '$timeout', function($scope, $timeout) {
    $scope.innerTest = '1';
    $timeout(function() {
        $scope.innerTest = '2';
    }, 3000);
}]);
angular.bootstrap(document.getElementById('divTest'), ['TestApp']);

or

var app = angular.module('TestApp', []);
app.controller('TestCtrl', ['$scope', function($scope) {
    $scope.test = 'a';
}]);
app.controller('InnerTestCtrl', ['$scope', function($scope) {
    $scope.innerTest = '1';

    setTimeout(function() {
        $scope.apply(function() {
            $scope.innerTest = '2';
        });
    }, 3000);
}]);
angular.bootstrap(document.getElementById('divTest'), ['TestApp']);

Comments

0

You should inject $timeout into your controller and use that instead of window.timeout.

Try this instead :

var app = angular.module("TestApp", []);
app.controller("TestCtrl", function($scope)
               {
                   $scope.test = "a";
               });
app.controller("InnerTestCtrl", function($scope, $timeout)
               {
                   $scope.innerTest = "1";
                   $timeout(function() 
                                     {
                                         $scope.innerTest = "2";
                                     }, 3000);
               });
angular.bootstrap(document.getElementById("divTest"), ["TestApp"]);

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.