2014-04-30 18 views
31

Czy istnieje sposób na uzyskanie nazwy kontrolera z bieżącego zakresu $ w AngularJS?

+0

Co próbujesz zrobić? Jeśli chcesz to wiedzieć, zawsze możesz pozwolić twojemu kontrolerowi na umieszczenie jego nazwy na '$ scope.controllerName'. –

+0

Masz rację, ale nie jest to użyteczne, ponieważ ja i wszyscy współpracujący ze mną powinniśmy pamiętać, aby umieścić nazwę kontrolera w zmiennej $ scope. –

Odpowiedz

5

Nie, nie jest to możliwe. Co jeśli $scope należy do dyrektywy? Nie ma właściwości, która może pobrać informacje o kontrolerze, do którego należy dany zakres.

+0

Twoje pytanie było pierwszym problemem, o którym myślałem. Więc nie ma sposobu, aby to zrobić bez zhakowania rdzenia Angular Jess? –

+1

@tommasocapelli Nie ma mowy. Musisz ręcznie nadać nazwę jako właściwość. – Engineer

+0

Dziękuję bardzo, to byłoby moje rozwiązanie, jeśli nie znalazłem żadnych innych sposobów na uzyskanie nazwy kontrolera w zakresie $. –

27

nie jestem pewien, że to dobre rozwiązanie, ale udało mi się wstrzykiwać $scope.controllerName użyciu tej techniki:

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(constructor, locals); 
      } 
     }]); 
}]); 

Następnie

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

Dzięki za udostępnienie. Kod działa poprawnie w kanale 1.2.x, ale jest uszkodzony w 1.3. demo: http://jsbin.com/muqipe/3/edit?html,console,output Po śledzeniu kodu źródłowego, stwierdziłem, że brakuje jeszcze dwóch argumentów dla wersji 1.3, więc powinno to być "funkcja (konstruktor, locale, później, indent) "i" $ delegate (konstruktor, locals, later, indent) ", dla twojego odniesienia. – Darkthread

+0

Masz wiadomość, że jesteś zbawicielem i masz taką samą możliwość udzielenia pierwszej odpowiedzi :) –

+0

Niesamowita sztuczka do celów debugowania – ganqqwerty

8

Działa to również dla mnie. Potrzebowałem funkcji celu ustalenia, czy nazwa kontrolera dopasowane danej trasie, przy użyciu „ngRoute”, aby wybrać sterownik, więc zrobiłem to:

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

Wtedy można go używać tak:

<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> 

Gdzie już dodałem trasy do mojej konfiguracji, np. coś

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

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

    }) 
2

pytanie jest już trochę stary, ale nadal może być pomocne dla niektórych z was ... Znalazłem sposób, aby uzyskać nazwę kontrolera ale działa tylko ze składnią Controller as. Teraz mogę łatwiej rejestrować dane bez konieczności ręcznego ponownego wpisywania nazwy kontrolera za każdym razem. Oto przykład:

// 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); 
}]); 

Jeśli chcesz to zrobić z DOM (od kodu javascript starszego typu), można też zrobić to w ten sposób:

// 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); 


Edycja
Próbowałem też sugestia Dave Syer to rzeczywiście działa na $scope jak na przykład:

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

To jest wspaniałe! Pracuję nad dużym projektem i dużo łatwiej jest znaleźć dokładnie kontroler, którego potrzebuję do obejrzenia dla danego elementu na stronie, klikając go i uruchomić 'kątowy.element ($ 0) .controller(). Konstruktor.name' w konsoli. –

11

Więc, oparte o n odpowiedź od Kevin Håkanson i komentarz z Darkthread, ten kod działa co najmniej 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); 
     }; 
    }]) 
}]); 
+0

to nie działa, jeśli zminimalizujesz aplikację, w jaki sposób zapewniasz nazwy argumentów nawet w minified pliku? –

+0

W moim przypadku używam gulp do wdrożenia mojej aplikacji. Tak więc udało mi się rozwiązać ten problem za pomocą: https://www.npmjs.com/package/gulp-ng-annotate –

+1

przesłałam zmianę, która pozwala na zminimalizowanie – coder

5

W funkcji fabrycznego kontrolera, po prostu spróbuj $ attrs usług

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

     var currentControllerName = $attrs["ngController"]; 

}]); 
2

tylko this.constructor.name wszędzie tam, gdzie zakres tej klasy jest dostępny po utworzeniu instancji.