1

I want to use "this" instead of $scope because I have a controller structure that doesn't initialize $scope:

.controller('MyCtrl', function($scope) {
    ... 
});

I must follow a tutorial with the structure above and put the $scope service to make it work.

Controller

(function() {
'use strict';

angular
.module('example.cancha')
.controller('CanchaController', CanchaController);

CanchaController.$inject = ['$state','$scope', 'canchaService'];

function CanchaController($state, $scope, canchaService) {
var vm = angular.extend(this, {
    canchasComplejo: []
    });



(function activate() {
    cargarCanchasComplejo();

})();

//funcion que llama al servicio para obtener las canchas del complejo
function cargarCanchasComplejo() {
    canchaService.obtenerCanchasComplejo()
        .then(function(canchasComplejo) {
            vm.canchasComplejo = canchasComplejo;
        $scope.groups = [];
        for (var i=0; i<canchasComplejo.length; i++) {
            $scope.groups[i] = {
                name: 'Cancha N°'+canchasComplejo[i].nroCancha+' ('+canchasComplejo[i].tipoCancha+')',
                items: ['Información','Habilitada','Ver Agenda'],
                show: false
            }
        };

      $scope.toggleGroup = function(group) {
        group.show = !group.show;
      };
      $scope.isGroupShown = function(group) {
        return group.show;
      };
    });
}
}
})();

As you can see, this is not the regular structure. Can I avoid using $scope using "this"? Thanks!

Liron Ilayev
  • 386
  • 4
  • 19
Faustino Gagneten
  • 2,564
  • 2
  • 28
  • 54
  • you have `CanchaController.$inject = ['$state','$scope', 'canchaService'];` which is doing the equivalent of injecting `$scope` inline. But if you don't want to use `$scope`, you could easily use `vm` instead, since you have defined it here.... – Claies Oct 07 '16 at 21:22

4 Answers4

0

Sure you can use so called vm pattern from John Papa. Check the article here https://daveceddia.com/convert-scope-to-controlleras/

Borys Generalov
  • 2,255
  • 17
  • 19
0

remove $scope injection from your controller:

CanchaController.$inject = ['$state','$scope', 'canchaService'];
function CanchaController($state, $scope, canchaService) {
  .....

should be:

CanchaController.$inject = ['$state', 'canchaService'];
function CanchaController($state, canchaService) {

then replace all $scope occurrences within controller scope with vm: $scope.groups = []; becomes vm.groups = [];

now be aware that in the HTML using this controller you cannot access groups directly, but you should use ng-controller="CanchaController as vm" (free fill to use any name instead of vm) and access groups with vm.groups. Your HTML might look like:

<div ng-controller="CanchaController as vm">
  <pre>{{ vm.groups | json }}</pre>
</div>

if this controller is used with routing or directive, then controllerAs: 'vm' should be set on JS level and not HTML

Andriy
  • 14,781
  • 4
  • 46
  • 50
  • Thanks for answer me. The problem is that when I click on the list never execute the function: vm.toggleGroup . This is now my controller: https://codeshare.io/Z1ZbP and this is my HTML code: https://codeshare.io/Sh7Ly – Faustino Gagneten Oct 07 '16 at 23:46
  • please upload your HTML code as well, where you call vm.toggleGroup() – Andriy Oct 07 '16 at 23:49
0

You should use the ControllerAs syntax instead of injecting the $scope into the function. This is the recommended way of settings up your controller ,see John Papa's style guide here. Specifically, look for rule [Style Y031].

Another option that you have, if you are using Angular 1.5.x, is to use Components instead of Controllers. When you declare the Component, you will specify the markup associated with it and that is all you have to do. The Component uses the ControllerAs syntax by default and it uses the alias $ctrl to reference the scope.

Latin Warrior
  • 902
  • 11
  • 14
-2

You can use "this" but it will always point on the function that triggers it. That will give you restrictions on the future or errors. It's 100% recommended to use $scope in angular so you can have a standard format on each function to avoid problems

Panagiotis Vrs
  • 824
  • 6
  • 16
  • 2
    I'm not sure where you got this "100% recommended to use `$scope`", since even the angular documentation says they only use `$scope` for quick examples; they recommend using Controller As, and `$scope` wasn't even built into Angular 2. – Claies Oct 07 '16 at 21:15
  • if you search around you will see why. Its getting confusing if you are using it in a more complex way and you want a function to be called from 4-5 ways. See also here http://stackoverflow.com/questions/11605917/this-vs-scope-in-angularjs-controllers – Panagiotis Vrs Oct 07 '16 at 21:22
  • my (personal) opinion is that using ControllerAs makes things *less* confusing, not more.... I wrote about it at length here http://stackoverflow.com/a/30644370/2495283 – Claies Oct 07 '16 at 21:24