3

In AngularJS they have $scope.$apply() method to update the UI when there's a model change that is not done through normal AngularJS means.

In the more recent tutorials they recommend using the <controller> as <object> style of instantiating the objects and use this as the scope from their example

.controller('TodoListController', function() {
var todoList = this;

However todoList.$apply() does not appear to work. Am I forced to use $scope.$apply() for this?

Archimedes Trajano
  • 35,625
  • 19
  • 175
  • 265

4 Answers4

7

Yes you have to use $scope.$apply(), but that's not a bad thing.

I had this same exact dilemma after reading that one should use controllerAs syntax. I even asked this question a few months later In an isolate scope directive is there any difference between defining variables on scope and defining variables on the controller?

The answer, after thinking about this for a while, is that controllerAs syntax doesn't mean an aversion to $scope, but a design pattern to prevent global state from being stored in $scope because that's when you start nesting scopes, which leads to a lot of problems.

$scope isn't an evil thing. It just lets you screw yourself over, but if you need to use it you shouldn't stop yourself from doing so.

Community
  • 1
  • 1
m0meni
  • 16,006
  • 16
  • 82
  • 141
2

Think you mean the "controller as" syntax, would be good to update the question title. You can still inject $scope and use it for registering watches or whatever, typically you aren't calling $apply within a controller though, typically it's done in a directive in response to some event that changes the model and needs to trigger Angular to refresh.

shaunhusain
  • 19,630
  • 4
  • 38
  • 51
2

The solution to this is pass this as bind parameter using either ES5 bind or angular.bind function

Eexmaple:

myApp.controller("myController",['$scope',function(s){
   this.name="val1";
   console.log("1: "+this.name);
   setTimeout(function(){
     console.log("2: "+this.name);
 
     s.$apply(function(){
       this.name="val2";  
     }.bind(this));
     console.log("3: "+this.name);
   }.bind(this));
  }]);
Julian Correa
  • 61
  • 1
  • 5
0

Directly in the controller this refers to the controller

.controller('TodoListController', function() {
    var todoList = this;

Here todoList is the controller.


However in a method defined on the scope, this refers to the scope. So

.controller('TodoListController', function($scope) {
    $scope.myFunction = function() {
        var todoList = this;
        ....

would have todoList pointing to the scope and you can do todoList.$apply()

potatopeelings
  • 40,709
  • 7
  • 95
  • 119