1

I have a grid with button that has k-grid-cancel-changes class. I would like to create a directive that will attach a click event to that button and call method on the page scope

    .directive('kGridCancelChanges', function () { 
               return {
                restrict: 'C',                
                scope: {
                    onCancelChanges: "&"
                },
                controller: function ($scope, $element, $attrs, $location) {
                    $element.click(function () {
                        $scope.onCancelChanges();
                    });
                }

            }
});

When I press button I can see $scope.onCancelChanges() fired from my directive but it never reaches function on the page scope.

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

I would appreciate any suggestions

4
  • 1
    did you try using $apply? Also try binding event inside link function Commented Oct 16, 2014 at 10:56
  • yes, I have tried: $scope.onCancelChanges(); $scope.$apply(); Commented Oct 16, 2014 at 10:59
  • create a demo that replicates problem Commented Oct 16, 2014 at 11:00
  • 1
    I think you should do it in link function Commented Oct 16, 2014 at 11:09

2 Answers 2

1

If you want to call a function in the scope it has to be provided like this:

<button class="k-grid-cancel-changes" on-cancel-changes="onCancelChanges()">test</button>

Demo: http://plnkr.co/edit/8vQ1wmdriGrDFGZwhqW2?p=preview

If for some reason you can't modify HTML code (say, it's rendered dynamically by Kendo) and can't add attribute, then you can only access the function to call via $parent scope reference:

$scope.$parent.onCancelChanges();

Demo: http://plnkr.co/edit/tpEEZs9VQunKXABud9yN?p=preview

And finally, if it's not principal to have isolated scope for your directive then you can simply call the function as it's the same scope:

.directive('kGridCancelChanges', function() {
    return {
        restrict: 'C',
        controller: function($scope, $element, $attrs, $location) {
            $element.click(function() {
                $scope.onCancelChanges();
            });
        }
    }
});

Demo: http://plnkr.co/edit/0OmlCJ6SgYU2GQRyBgYj?p=preview

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

8 Comments

Hi, $scope.$parent.onCancelChanges(); seems to be working, but I thought using $parent is a bad practise?
Yes, I would avoid using $parent. Just explaining to you your options. I would go with #1 or #3.
I have removed isolated scope and it is finally working. Thank you. Any reasons why I should use isolated scope in this case ?
If you only need to create an event handler, then you don't need isolated scope. You would use it if you directive were to create some scope variables.
Yes in your case you'd better use link function, this is where we bind event handlers to DOM normally.
|
1

You can create you directive like this:

app.directive('myDir', function () {

    return {
        restrict: 'C',
        scope: {
            foo: '&'
        },
        link: function(scope,elem){
            elem.on('click',function(){
               scope.foo(); 
            });
        }};

});

or use controller function instead of link if you need:

    controller: function($scope,$element){
        $element.on('click',function(){
           $scope.foo(); 
        });
    }};

Note that angular's jqLite has no element.click function.

Here is fiddle: http://jsfiddle.net/cxo77xb4/2/

2 Comments

Thank you, for great example. I am sure I will use it in the future but in this case I can't modify html
@witpo you don't have to modify html. Just change the foo for the onCancelChanges

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.