Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When to use Angular's $element

I've seen a few code examples where where $element is injected into an angular controller. I've spent some time trying to find any documentation for $element but havent been able to find any in angulars official docs.

What is the $element service used for, when should I use it, and what are the best practices around it usage?

like image 349
elliot-j Avatar asked Dec 18 '15 16:12

elliot-j


People also ask

What is the purpose of a selector?

A selector is one of the properties of the object that we use along with the component configuration. A selector is used to identify each component uniquely into the component tree, and it also defines how the current component is represented in the HTML DOM.

How do you use ViewChildren?

The Viewchild can also be used to query HTML elements. First, assign a Template variable ( #para in the example below) to the HTML element. You can then use the ViewChild to query the element. ViewChild returns a ElementRef , which is nothing but a wrapper around the native HTML element.

What is the use of Angular elements?

Angular Elements are regular Angular Components that have been packaged as Custom Elements. Custom Elements are part of Web Components and allow us to create new HTML elements, that can be used directly on our page, or by using a polyfill if they are not supported by the browser.

What is the use of NG Dblclick?

Definition and Usage The ng-dblclick directive tells AngularJS what to do when an HTML element is double-clicked. The ng-dblclick directive from AngularJS will not override the element's original ondblclick event, both are executed.


3 Answers

$element is a jqlite (or jQuery if it is available) wrapped object containing a reference to some DOM objects as well as some helpful functions to interact with them. Any time you need to make changes to the DOM you would use $element.

For example... If you needed to add a class to a directives DOM object you would inject $element and call

$element.addClass("my-class")

You can see the documentation here

like image 83
Marie Avatar answered Sep 23 '22 08:09

Marie


When you inject $element into a controller you get a JQlite wrapped version of the element that the controller is called from. In the case of a directive controller, it would be whatever element the directive is attached to. The only mention in the docs I could find was under the $compile description.

You can see that in the following example:

angular.module('myApp', [])
  .controller('testCtrl', function($scope, $element) {
    console.log($element);
  })
  .directive('testDirective', function() {
    return {
      controller: function($scope, $element) {
        console.log($element);
      }
    }
  })
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>

<body ng-app="myApp">
  <div ng-controller="testCtrl" id="controller">Controller</div>
  <div test-directive id="directive">Directive</div>
</body>

The best practice is that you don't make any DOM changes except for in a directive and even more specifically typically in the link function. That being the case you almost never want to use the $element in a controller because that most likely means you are approaching the solution from the wrong angle.

like image 39
Matthew Green Avatar answered Sep 22 '22 08:09

Matthew Green


I've spent some time trying to find any documentation for $element but havent been able to find any in angulars official docs.

$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);
like image 33
georgeawg Avatar answered Sep 26 '22 08:09

georgeawg