gene
gene

Reputation: 2108

AngularJS: Cannot get my directive working

I'm in my second day of learning AngularJS and have a simple example of how to change DOM on user's action, which somehow does not work for me. Here is an examlple:

html file:

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
   <title></title>
   <script src="../Scripts/angular.min.js"></script>
   <script src="../Scripts/Controllers/app.js"></script>
   <script src="../Scripts/jquery-1.4.1.min.js"></script>
</head>
<body ng-app="myApp">
   <my-widget>
      <p>Hello World</p>
   </my-widget>
</body>
</html>

File with directive's action:

var app = angular.module('myApp', []);

app.directive("my-widget", function () {
    var linkFunction = function (scope, element, attributes) {
        var paragraph = element.children()[0];
        $(paragraph).on("click", function () {
            $(this).css({ "background-color": "red" });
        });
    };

    return {
        restrict: "E",
        link: linkFunction
    };
});

Nothing happens when clicking on paragraph. Cannot find why.

Upvotes: 0

Views: 1356

Answers (1)

David L
David L

Reputation: 33873

Simply change your directive name to camelCasing, which angular will translate to my-widget. In addition, the jQuery $ alias is not available and shouldn't be used with angular. You already have the element, so interact with it directly, using element.css() to change css properties.

In addition, based on the comments below, it makes more sense to change the restrict to either "A" or "EA" and apply the directive directly to the element you intend to change.

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
   <title></title>
   <script src="../Scripts/angular.min.js"></script>
   <script src="../Scripts/Controllers/app.js"></script>
</head>
<body ng-app="myApp">
  <div my-widget style="width: 300px; height: 200px; background-color: orange;">
    <p>Hello World</p>
  </div>
</body>
</html>

This also saves you from needing to traverse to the child elements.

app.directive("myWidget", function () {
    var linkFunction = function (scope, element, attributes) {
        element.on("click", function () {
          element.css("background-color", "red");
        });
    };

    return {
        restrict: "EA",
        link: linkFunction
    };
});

See this working plunker.

Per the documentation:

Angular normalizes an element's tag and attribute name to determine which elements match which directives. We typically refer to directives by their case-sensitive camelCase normalized name (e.g. ngModel). However, since HTML is case-insensitive, we refer to directives in the DOM by lower-case forms, typically using dash-delimited attributes on DOM elements (e.g. ng-model).

The normalization process is as follows:

Strip x- and data- from the front of the element/attributes. Convert the :, -, or _-delimited name to camelCase.

Upvotes: 3

Related Questions