1

So I was just testing some stuff and I was writing a directive like this:

HTML

<div ng-app="app">
    <my-directive>
        hi {{name}}
    </my-directive>
</div>

JS

angular.module("app", [])

.directive("myDirective", function () {
    return {
        scope:true,
        restrict: "E",
        link: function (scope, elem, attr) {
            scope.name="yourname";
            elem.onclick = function () { console.log("change name");}
        }

    }
})

But the onclick function never fires. And I know this is not how I should properly write in Angular, but it was just something I did on the fly. However, this works:

angular.module("app", [])

.directive("myDirective", function () {
    return {
        scope:true,
        restrict: "E",
        link: function (scope, elem, attr) {

            scope.name="yourname";
            elem.on("click", function () {console.log("change name")});
        }

    }
})

And here a fiddle: fiddle

What is going on here? Is it outside the Angular world and should I use scope.applyor something to get it to work. I am just curious why vanilla javascript is not ok in this case. But this is also a good lesson to keep myself focused on thinking the Angular way.

Maybe someone that can explain what is going on? TIA

9
  • The fiddle doesn't work for me, but I would expect you need to do elem[0].onclick - since elem is a jqLite-wrapped object. Commented Jun 2, 2015 at 18:40
  • 1
    Aside: you're doing restrict: "E" but your markup is using it as an attribute, or restrict: "A" -- Edit: your question is right, your fiddle is wrong. Sorry for the confusion Commented Jun 2, 2015 at 18:41
  • Hah .. I was looking at the question, checked the element/attribute thing, looked right and then didn't notice it in the jsfiddle :) Commented Jun 2, 2015 at 18:44
  • With Restrict E, the link function never executes. Commented Jun 2, 2015 at 18:45
  • 1
    the fiddle is different from the code here ... that's probably where the confusion comes from. Commented Jun 2, 2015 at 18:55

2 Answers 2

5

It is because elem inside link function is a jQuery object. You should get the html dom element using elem[0] and then try.

angular.module("app", [])

.directive("myDirective", function () {
    return {
        scope:true,
        restrict: "E",
        link: function (scope, elem, attr) {
            scope.name="yourname";
            elem[0].onclick = function () { console.log("change name");}
        }

    }
})
Sign up to request clarification or add additional context in comments.

2 Comments

Yes this is the answer I was looking for. It was not clear to me at all that elem was a jQuery object and so I guess attr is also a jQuery object?
attr is an object containing all the attributes key/value pair provided in the directive.
2

Here is a new fiddle that gets your original code working, but the code in the question looks very different now.

One problem was your "name" property wasn't binding because you had an isolate scope where name was being set, but then transclude: true was causing angular to bind against an outer scope, so the name never displayed. Also there was no template that was pulling in the transcluded content, leaving you with an empty html element. This new fiddle is mostly your original code but the event handler works without going straight to the dom element as in the other posted answer.

https://jsfiddle.net/ghkfjjh6/9/

angular.module("app", [])

.directive("myDirective", function () {
    return {
        transclude: true,
        restrict: "A",
        template: '<div ng-transclude></div>',
        link: function (scope, elem, attr) {
            console.log("link ran!");
            scope.name = "miek";
            console.log(scope);
           elem.on('mouseenter', function() {
               console.log("entered");
            })
        }

    }
})

<div ng-app="app">
    <div my-directive>
        hi {{name}}!
    </div>
</div>

4 Comments

Hi I appreciate your help, but I posted the wrong fiddle. The question was right, the fiddle was wrong. Sorry about that. See accepted answer for my original problem.
Ok, so your question doesn't require doing a transclude?
It seems like soon, you are going to realize the event handler works but the directive ultimately doesn't do what you want, but maybe not. I just figured it was supposed to use transclusion as well as have event handlers.
No, sorry for the confusion. I am trying to go in depth with directives so I fiddle around with everything and sometimes I loose track of what fiddle I made.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.