Super Babaca
Super Babaca

Reputation: 1655

Element or $(element) in a directive

In a lecture Deep dive into custom directives Dave Smith gives an example:

.directive('selectAll', function () {
  return {
      restrict: 'A',
      link: function( scope, element ) {
        element.mouseup( function ( event ) {
          event.preventDefault();
        } );
        element.focus( function () {
          element.select();
        } );
      }
  };
})

but as a result I have an error:

TypeError: undefined is not a function
at link (http://localhost:8080/modules.html:108:21)
at invokeLinkFn (http://localhost:8080/lib/angular.js:8111:9)
at nodeLinkFn (http://localhost:8080/lib/angular.js:7623:11)
at compositeLinkFn (http://localhost:8080/lib/angular.js:6991:13)
at compositeLinkFn (http://localhost:8080/lib/angular.js:6994:13)
at publicLinkFn (http://localhost:8080/lib/angular.js:6870:30)
at http://localhost:8080/lib/angular.js:1489:27
at Scope.$eval (http://localhost:8080/lib/angular.js:14123:28)
at Scope.$apply (http://localhost:8080/lib/angular.js:14221:23)
at bootstrapApply (http://localhost:8080/lib/angular.js:1487:15)

When I put $(element) instead of element everything is fine:

.directive('selectAll', function () {
  return {
      restrict: 'A',
      link: function( scope, element ) {
        $(element).mouseup( function ( event ) {
          event.preventDefault();
        } );
        $(element).focus( function () {
          $(element).select();
        } );
      }
  };
})

2 questions: why? and how to make the first behavior a default?

Upvotes: 1

Views: 224

Answers (3)

Nico Napoli
Nico Napoli

Reputation: 1887

From AngularJS documentation:

If jQuery is available, angular.element is an alias for the jQuery function. If jQuery is not available, angular.element delegates to Angular's built-in subset of jQuery, called "jQuery lite" or "jqLite."

Since jqLite implements only the most commonly needed functionality, if you want to use "element.select" and not "$(element).select" you need to load jQuery library before DOMContentLoaded event fired.

Now angular.element will be an alias of jQuery function and then those two pieces of code will be equivalent.

Upvotes: 1

Michael Kang
Michael Kang

Reputation: 52867

They should be equivalent if you are including the jquery library in the correct order. Make sure that you are including the jQuery library before the angularjs library.

Upvotes: 1

Todd
Todd

Reputation: 5454

Yeah, this can be confusing.

Angular uses jQLite, a subset of jQuery. $(element) would be a jquery object, and could therefore have jquery functions called upon it. Calling `document.createElement('div').css("background", "green"), for instance, would not work because it is not a jquery-wrapped element.

Hope this helps!

Upvotes: 3

Related Questions