web-dev-qa-db-fra.com

Obtenir le nom du contrôleur à partir de $ scope

Existe-t-il un moyen d’obtenir le nom du contrôleur à partir de la portée actuelle de $ AngularJS?

34
tommaso capelli

Non ce n'est pas possible. Que faire si $scope appartient à la directive? Aucune propriété ne peut extraire des informations sur le contrôleur auquel appartient l'étendue.

7
Engineer

Je ne suis pas sûr que ce soit une bonne solution, mais j'ai pu injecter $scope.controllerName avec cette technique:

app.config(['$provide', function ($provide) {
    $provide.decorator('$controller', [
        '$delegate',
        function ($delegate) {
            return function(constructor, locals) {
                if (typeof constructor == "string") {
                    locals.$scope.controllerName =  constructor;
                }

                return $delegate.apply(this, [].slice.call(arguments));
            }
        }]);
}]);

Ensuite

app.controller('SampleCtrl', ['$scope', '$log', function ($scope, $log) {
    $log.log("[" + $scope.controllerName +"] got here");
}]);
30
Kevin Hakanson

Donc, basé sur la réponse de Kevin Hakanson et le commentaire de Darkthread, ce code fonctionne avec au moins 1.3.15: dev

app.config(['$provide', function ($provide) {
    $provide.decorator('$controller', ['$delegate', function ($delegate) {
        return function (constructor, locals, later, indent) {
            if (typeof constructor === 'string' && !locals.$scope.controllerName) {
                locals.$scope.controllerName = constructor;
            }
            return $delegate(constructor, locals, later, indent);
        };
    }])
}]);
11
Thomas Kekeisen

Cela fonctionne aussi pour moi. J'avais besoin d'une fonction pour déterminer si le nom du contrôleur correspondait à une route donnée, en utilisant 'ngRoute' pour sélectionner un contrôleur, je l'ai donc fait:

app.controller('navigation', function($scope, $route) {
  $scope.tab = function(route) {
    return $route.current && route === $route.current.controller;
  }
}

Ensuite, je peux l'utiliser comme ça:

<div ng-controller="navigation" class="container">
    <ul class="nav nav-pills" role="tablist">
        <li ng-class="{active:tab('home')}"><a href='#/'>home</a></li>
        <li ng-class="{active:tab('dashboard')}"><a href='#/dashboard'>dashboard</a></li>
    </ul>
</div>

Où j’ai déjà ajouté des routes à ma configuration, par exemple quelque chose comme

angular.module('app', [ 'ngRoute' ]).config(
    function($routeProvider) {

        $routeProvider.otherwise('/');
        $routeProvider.when('/', {
            templateUrl : 'home.html',
            controller : 'home'
        }).when('/dashboard', {
            templateUrl : 'dashboard.html',
            controller : 'dashboard'
        });

    })
8
Dave Syer

Dans la fonction d'usine du contrôleur, essayez simplement $ attrs service

app.controller("MyController", ["$attrs", function($attrs){

      var currentControllerName = $attrs["ngController"];

}]);
5
Kevin Dai

La question commence à devenir un peu ancienne mais elle pourrait quand même être utile à certains d'entre vous ... J'ai trouvé un moyen d'obtenir le nom du contrôleur mais cela ne fonctionne qu'avec une syntaxe Controller as. Je peux maintenant me connecter plus facilement sans avoir à réécrire manuellement le nom de mon contrôleur à chaque fois. Voici un exemple:

// a simple route with controller as syntax
$routeProvider.when(
    '/contact', 
    { 
        templateUrl: 'home/contact', 
        controller: 'ContactController as vm' 
    }
);

// controller
app.controller("ContactController", ["$log", function ContactController($log) {
    var vm = this;
    $log.log(vm.constructor.name); 
}]);

Si vous voulez le faire à partir du DOM (à partir de code javascript hérité), vous pouvez également le faire de la manière suivante:

// scope element via the DOM
var scope = angular.element($(element)).scope();    
console.log(scope.this.vm.constructor.name);

// controller element via the DOM
var controller = angular.element($(element)).controller();    
console.log(controller.constructor.name);


Modifier
Aussi essayé la suggestion de Dave Syer cela fonctionne réellement sur $scope comme par exemple:

app.controller("ContactController", ['$route', function ContactController($route) {
  console.log($route.current.controller);
}]);
2
ghiscoding

juste this.constructor.name partout où la portée de cette classe est disponible une fois instanciée.

2
IzzakActive

Si vous déboguez à partir de la console, cela m'a semblé utile:

  1. Sélectionnez l'élément dans l'interface utilisateur dont vous recherchez le contrôleur dans les outils de développement Chrome.
  2. Entrée dans la console: angular.element($0).controller().__proto__

Cela vous donnera le prototype du contrôleur, à l'intérieur de son constructeur, il y a FunctionLocation qui correspond à un fichier. Si vous configurez vos contrôleurs un par fichier comme vous le devriez, vous y trouverez votre contrôleur. C'est encore mieux si vous nommez vos fichiers comme contrôleur, je ne vois pas pourquoi vous ne le feriez pas.

Je sais que ce n'est pas exactement ce que vous avez demandé, mais je trouve cela utile et extrêmement facile à utiliser directement depuis les outils de développement.

0
DanteTheSmith

Il est possible d'obtenir le champ d'application de la directive ainsi que celui du contrôleur à l'aide de jQuery.

 window.top.$('[ng-controller="mainCtrl"]').scope(); // get scope of controller

 window.top.$('[epubby-page-view]').scope(); // get scope of directive

Nous pouvons exécuter une méthode ou mettre à jour n'importe quelle variable de n'importe où en utilisant ces méthodes d'extraction de portée.

Par exemple: Considérons que nous voulons exécuter une méthode à partir du contrôleur mainCtrl, Nous avons juste besoin d'appeler directement une méthode comme suit:

var myData = window.top.$('[ng-controller="mainCtrl"]').scope().getData();
0
Sandip Jadhav