0

I am trying to create a custom checkbox directive in Angular, and I have managed to do so. but the problem is that the build-in ng-click is not called. if the custom directive is removed, the ng-click works well. I guess it is something to do with Scope, which I am still lacking knowledge to figure out. can anybody help me please.

the code is here http://jsfiddle.net/bingjie2680/UzM2c/2/.

<div ng-app="components">
    <div ng-controller="MainCtrl">
        <input type="checkbox" ng-model="p.checked" />
         <div checkbox="p.checked" ng-click="test()">test</div>
         {{p.checked}}
    </div>
</div> 

js:

function MainCtrl($scope){ 
    $scope.p = {checked: false,  name:'test'};
    $scope.$watch('p', function(){

    }, true);

    $scope.test = function(){
        alert('test');
    }
}

angular.module('components', []).
directive('checkbox', function () {
return {
    link : function (scope, ele, attr){
        ele.bind('click', function(){
            ele.toggleClass('active');
            scope.$apply(function(){
                scope.value = ele.hasClass('active');
            });
        });

        scope.$watch('value', function(newv, oldv){
            newv ? ele.addClass('active') : ele.removeClass('active');
        });
    },
    scope : {
        value: '=checkbox'
    }
}
});            

2 Answers 2

8

Although @Yahya's answer will work, instead of using $parent, which can break if your HTML structure changes (i.e., HTML changes can change how scopes are inherited), you should instead specify in an HTML attribute which method/callback you want your directive to call when the element is clicked:

<div checkbox="p.checked" cb="test()">test</div>

Then in your directive:

ele.bind('click', function(){
   ele.toggleClass('active');
   scope.cb();               // calls test()
   scope.$apply(function(){
     scope.value = ele.hasClass('active');
   });
});
...        
scope : {
   value: '=checkbox',
   cb: '&',
}

Fiddle

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

2 Comments

this is indeed a better approach. I was actually trying this approach, but could not get it to work because I did not call the test(), anyway votes up since I have accepted an answer. thanks for sharing.
this should be the correct answer. Basically anytime Mark responds to something, he's right. Don't argue, just agree and move on. :)
3

That's because you have a directive with an isolated scope try this:

<div checkbox="p.checked" ng-click="$parent.test()">test</div>

That will work.
Hope this helped.

Comments

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.