4

In AngularJS there are two styles of writing controllers, the "the controller as syntax" and the "'attach to $scope' style of controller" (both quotes from the ngController documentation.) There are several questions on StackOverflow comparing these styles, for example this vs $scope in AngularJS controllers and Performance differences between controller functions defined on $scope or this - AngularJS.

I have a method on a controller which needs to prompt AngularJS after a model update. Using the $scope style of controller I can do that thus:

myApp.controller('MainController', ['$scope', function($scope) {
    $scope.content = "[Waiting for File]";
    $scope.showFileContent = function(fileContent) {
        $scope.content = fileContent;
        $scope.$apply();
    };
}]);

But if I write the controller using 'this'

myApp.controller('MainController', function () {
    this.content = "[Waiting for File]";
    this.showFileContent = function(fileContent){
        this.content = fileContent;
    };
});

how do I invoke $apply()?

1
  • You can get around using $apply by wrapping your async task with $q. Have you considered that? Commented Dec 15, 2014 at 18:24

1 Answer 1

4

If you really need $scope, you still can inject it. Assuming "controller as" syntax:

myApp.controller('MainController', function($scope) {
   this.content = "[Waiting for File]";
   $scope.$apply(); // etc.
});

The question is, do you really need to run $scope.$apply() there? Assuming you are using it properly in "controller as" syntax, it should see it:

<div ng-controller="MainController as main">
  <div id="content">{{main.content}}</div>
</div>

Then div#content will be updated when you update your this.content var. Mind you, you need to be careful of how you use this, so you might need:

myApp.controller('MainController', function($scope) {
   var that = this;
   this.content = "[Waiting for File]";
   this.showFileContent = function(fileContent){
       // 'this' might not be set properly inside your callback, depending on how it is called.
       // main.showFileContent() will work fine, but something else might not
       that.content = fileContent;
   };
});
Sign up to request clarification or add additional context in comments.

3 Comments

Thanks @deitch. I was not expecting to need to use $source.$apply() either, but my html is not re-rendering without it.
Oh, I see! You are calling showFileContent() in response to a FileReader event, so the callback is executed outside of the Angular context. Is that it?
Yeah, also your onchange executes stuff outside the Angular context. I will comment on there. It is a separate question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.