14

If i'd like to use the "Controller as ..." syntax in Angular, how should I approach things like $scope.$on(...) that i need to put inside the controller?

I get an impression i could do it some other way than the one shown below. Here, to get $scope.$on working i bind "this" to the callback function. I tried to invoke $on on "this" inside the controller but it didn't work.

Could you give me a hint here or if i'm completely messing up, could you point me to some right way to do it? Thanks.

main.js:

angular.module('ramaApp')
.controller('MainCtrl', ['$scope', '$location', function ($scope, $location) {

    this.whereAmINow = 'INDEX';

    $scope.$on('$locationChangeStart', function(event) {

        this.whereAmINow = $location.path();

    }.bind(this));

    this.jumpTo = function(where) { $location.path(where); }
}]);

index.html:

<div ng-controller="MainCtrl as main">

    <p>I am seeing the slide named: {{ main.whereAmINow }}</p>

    <div ng-click="main.jumpTo('/slide1')">Slide 1</div>
    <div ng-click="main.jumpTo('/slide2')">Slide 2</div>
    <div ng-click="main.jumpTo('/slide3')">Slide 3</div>

</div>
Greg
  • 205
  • 5
  • 14

3 Answers3

7

As far as I know, you need to inject $scope if you want $scope watchers/methods. ControllerAs is just syntactic sugar to enable to see more clearly the structure of your nested controllers.

Three ideas though which may simplify your code.

  1. Use var vm = this, in order to get rid of the bind(this).

    var vm = this;
    vm.whereAmINow = "/";
    
    $scope.$on('$locationChangeStart', function(event) {
        vm.whereAmINow = $location.path();
    });
    
    vm.jumpTo = function(where) {
        $location.path(where);
    }
    
  2. The whole whereamINow variable makes sense putting it into the initialization of app aka .run() (before config) since I assume it's a global variable and you don't need to use a $scope watcher/method for it.

  3. Another option is to use a factory to make the changes persist, so you simply create a location factory which holds the current active path.

Samir Alajmovic
  • 3,247
  • 3
  • 26
  • 28
0

Inject $scope and your controller is accessible by whatever you named it

EG:

$stateProvider
  .state('my-state', {
    ...
    controller: 'MyCtrl',
    controllerAs: 'ctrl',
    ...
  });



.controller('MyCtrl', function($scope) {
  var $this = this;
  $scope.$on('ctrl.data', function(new, old) {
    // whatevs
  });
  $timeout(function() {
    $this.data = 'changed';
  }, 1000);
});
Leo
  • 13,428
  • 5
  • 43
  • 61
ilovett
  • 3,240
  • 33
  • 39
-2

Ok, i think people just do the same, just as in this question:

Replace $scope with "'controller' as" syntax

Community
  • 1
  • 1
Greg
  • 205
  • 5
  • 14