50

I am new to angularjs, I know that $scope represent a connection between the controller and the view, But is there a way besides looking for class="ng-scope" to get the scope element, I mean something like that:

function someControllerFunc($scope){
       $scope.element;
}

I know that same controller can be assigned to multiple scopes, So maybe it is not possible.

sudo bangbang
  • 27,127
  • 11
  • 75
  • 77
Aviel Fedida
  • 4,004
  • 9
  • 54
  • 88
  • What do you mean by getting the scope element? Do you mean the element the controller is declared on? – Mike Cheel Jan 23 '14 at 14:48
  • 4
    You should never access any DOM elements from within the controller! This is exactly the type of behavior Angular is trying to discourage!! – Joseph Silber Jan 23 '14 at 14:49
  • 1
    Any sort of DOM interaction should be done only via directives, never in a controller. – Abhishek Jain Jan 23 '14 at 14:49
  • possible duplicate of [How do i get current scope dom-element in AngularJS controller?](http://stackoverflow.com/questions/12960701/how-do-i-get-current-scope-dom-element-in-angularjs-controller) – apohl Jan 23 '14 at 14:56

4 Answers4

72

You can pass in the element to the controller, just like the scope:

function someControllerFunc($scope, $element){

}
apohl
  • 1,913
  • 27
  • 30
  • Should i include any dependency in the module?, Because $element is undefined. – Aviel Fedida Jan 23 '14 at 15:00
  • 15
    Actually, after more research, `$element` is not a good way to access the element, and is being [depricated](http://stackoverflow.com/questions/12960701/how-do-i-get-current-scope-dom-element-in-angularjs-controller). You probably want to use a [directive](http://docs.angularjs.org/guide/directive) for this. – apohl Jan 23 '14 at 15:42
  • 6
    @apohl, where did you read that it's being deprecated? The link you provided doesn't say anything about that and I can't find anything in the documentation that says it's being deprecated... – kentcdodds Jul 18 '14 at 15:14
  • @kentcdodds it explains it in the comments under the accepted answer. – apohl Jul 25 '14 at 16:09
  • 5
    @apohl, there's no mention of `$element` being deprecated in any of those comments... I need to know whether it's going to be deprecated because we use it in our app in several places, so I'd want to watch out for that when we upgrade.... – kentcdodds Jul 28 '14 at 16:33
  • 3
    @kentcdodds Ok, you're right. Deprecated was the wrong term. So that method will work, but it's not the suggested use. – apohl Jul 28 '14 at 17:17
  • 9
    @apohl -- Sometimes you can't help it, such in the case of a modal/popup scenario where you're essentially creating directives by hand using the `$compile` service to bind elements with controllers. I agree, it's a messy and non-elegant solution, but programming is full of those, right? =) – EHorodyski Jul 27 '15 at 13:52
  • Is it poor too, if that controller used inside directive? – vp_arth Nov 10 '15 at 06:44
14

$element is one of four locals that $compileProvider gives to $controllerProvider which then gets given to $injector. The injector injects locals in your controller function only if asked.

The four locals are:

  • $scope
  • $element
  • $attrs
  • $transclude

The official documentation: AngularJS $compile Service API Reference - controller

The source code from Github angular.js/compile.js:

 function setupControllers($element, attrs, transcludeFn, controllerDirectives, isolateScope, scope) {
    var elementControllers = createMap();
    for (var controllerKey in controllerDirectives) {
      var directive = controllerDirectives[controllerKey];
      var locals = {
        $scope: directive === newIsolateScopeDirective || directive.$$isolateScope ? isolateScope : scope,
        $element: $element,
        $attrs: attrs,
        $transclude: transcludeFn
      };

      var controller = directive.controller;
      if (controller == '@') {
        controller = attrs[directive.name];
      }

      var controllerInstance = $controller(controller, locals, true, directive.controllerAs);
georgeawg
  • 48,608
  • 13
  • 72
  • 95
3

I dont know what do you exactly mean but hope it help you.
by this directive you can access the DOM element inside controller
this is sample that help you to focus element inside controller

.directive('scopeElement', function () {
    return {
        restrict:"A", // E-Element A-Attribute C-Class M-Comments
        replace: false,
        link: function($scope, elem, attrs) {
            $scope[attrs.scopeElement] = elem[0];
        }
    };
})

now, inside HTML

<input scope-element="txtMessage" >

then, inside controller :

.controller('messageController', ['$scope', function ($scope) {
    $scope.txtMessage.focus();
}])
Sadegh Teimori
  • 1,348
  • 12
  • 12
  • 1
    I think you should have such functionality using a directive not element, check http://embed.plnkr.co/SgRVM6OIBOUV0hhia70X/, but still a good example to show how to get the element inside a controller – Basheer AL-MOMANI Jan 30 '19 at 11:37
0

Create custom directive

masterApp.directive('ngRenderCallback', function() {
    return {
        restrict: "A",
        link: function ($scope, element, attrs) {
            setTimeout(function(){ 
                $scope[attrs.ngEl] = element[0];
                $scope.$eval(attrs.ngRenderCallback);               
            }, 30);
        }
    }
});

code for html template

<div ng-render-callback="fnRenderCarousel('carouselA')" ng-el="carouselA"></div>

function in controller

$scope.fnRenderCarousel = function(elName){
    $($scope[elName]).carousel();
}