Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

When I declare a directive to use that accesses a controller function, it cannot find the controller.

Here is my directive declared in app.js:

app.directive("delete", function() {
    return {
        restrict: 'A',
        link: function(scope, elem, attr, ctrl) {
            elem.bind('click', function(e) {

                alertCtrl.alert();

            });
        }
    }
});

Here is my controller:

app.controller('AlertController',  function() {

    this.alert = function() {
        alert('Ahah!');
    }


});

And here is my HTML:

<div ng-controller="AlertController as alertCtrl">

    <div ng-repeat="i in [1,2,3]">

        <img src='image.png' delete />

    </div>

</div>

If I click on the image, I get no alert and the console says that alertCtrl is not defined. How come alertCtrl is not defined when you click on the image with the delete directive on it?

If I change the controller to have $scope.alert = function()... it works fine. But I do not want this.

Also, is this the proper way to handle such a situation? If not, what is the best practice?

share|improve this question

1 Answer 1

up vote 2 down vote accepted

You need to call, it on the scope. scope has the property alertCtrl which is your controller instance. Your controller alias (alertCtrl) is available when you bind it on the html since scope is implicit there. but when you do it in the javascript i.e in the directive, or another controller you would need to get the controller instance (defined as alias) from the scope as a property.

 scope.alertCtrl.alert();

Plnkr

share|improve this answer
    
This worked, but could you possibly give a deeper & more comprehensive explanation, please? Is that the way it SHOULD be done? Is my overall code structure the "Angular" way? –  karns Sep 5 '14 at 1:09
    
I have explained it in my answer... Basically the alias is a property on the scope object, on the html it is implicit because you dont use the property scope since everything is bound with the scope. When you use alias it is basically scope.alertCtrl, which lets you use it as alertCtrl.whatever in the html, but when you are on the directive there is no variable called alertCtrl available, because it does not exist it is just a property on the scope. –  PSL Sep 5 '14 at 1:12
    
Is that the way it SHOULD be done? It depends, this is angular way only otherwise why would you even need to use scope on the controller/directive etc.. You would just go with some global variables (which definitely is not angular way). There are many other ways to use a directive, inherited scope, isolated scope, 2 way bindings, function bindings, text binding and soon, it it upto you to chose what you need. If you were able to do it as alertCtrl.alert() then it is definitely not angular way because your directive has no idea where it comes from. Hope i have clarified enough.. :) –  PSL Sep 5 '14 at 1:13
    
I am sorry, I did not see your whole answer thanks to my browser rendering issues (of which I have another question on Super User for). Thank you much! –  karns Sep 5 '14 at 1:15
    
@karns hey np. don't use IE.. :D You are welcome... –  PSL Sep 5 '14 at 1:16

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.