1

I have some Angular 1.4 code I've inherited, which has some bizarre scope issues I'm trying to tidy up - and I'm stuck on a particular one.

I have an ES6 Class controller (Babelified) - in it, I have a method like this

save(data) {
    this.validate(data);
    .... do some more stuff
}

I also have a View and model and html and all that good stuff. In it I have a custom directive for radio buttons - like this

<radio onupdate="vm.save" data="model.myradio1" />

My Radio directive seems to have two bindings for onupdate & data

.directive('radio', () => {
    return {
        restrict: 'E',
        replace: true,
        templateUrl: 'radio',
        scope: {
            data: '=',
            onupdate: '='
        }
    };
})

the template contains

ng-click="radio.onupdate($parent.data);" <-- This looks suspect but no idea what it does!

However - this then explodes in ways I wouldn't have expected:

this.validate is not a function

I can see how this happened - this now refers to the radio buttons scope. But how do I fix it? I'm pretty new to Angular.

6
  • stackoverflow.com/questions/35854586/… . see the answer in this post. access function instead of variable. Commented Mar 10, 2016 at 7:23
  • Post directive code: its scope configuration and how onupdate is called from inside. Commented Mar 10, 2016 at 7:30
  • I'm not sure how this helps me rebind this to my controller rather than the directive scope? Commented Mar 10, 2016 at 7:35
  • Once again, post necessary information, your post missing the most important parts I highlighted. Commented Mar 10, 2016 at 7:37
  • Sorry - that was a response to the person before you - post updated with the directive definition and an excerpt from the template Commented Mar 10, 2016 at 7:39

3 Answers 3

1

In order to invoke a controller method from the directive you need to create a "reference" function with & scope configuration:

.directive('radio', () => {
    return {
        restrict: 'E',
        replace: true,
        templateUrl: 'radio',
        scope: {
            data: '=',
            onupdate: '&'
        }
    };
})

Then from directive template you need to call it like this:

ng-click="onupdate({data: $parent.data});"

And finally the usage of the radio directive becomes:

<radio onupdate="vm.save(data)" data="model.myradio1" />
Sign up to request clarification or add additional context in comments.

Comments

0

Hello I stick to your question title 'how to call controller function from directive'.

I've made an example that uses a <select> element and calls the controller function $scope.filterHall() to send the selected object, whenever the user changes value.

Directive (i get the changeHall function and i call it into the template,see below ):

.directive('eventHallsList', function($timeout, $log, $http, $compile) {
    return {
      restrict: 'AE',
      replace: true,
      scope: {
        changeHall: '&',
        items: '=',
        model: '='
      },
      templateUrl: 'mytemplate.tpl.html',
      link: function(scope, element, attrs) {
      }

    }
  });

Template: Into the select element everytime the user selects a value, i call the changeHall() which is bind to the controller's function $scope.filterHall() , and it pass the object.

<select style="color:#337ab7"
        ng-change="changeHall({value:model})" ng-model="model"
        ng-options="item as item.name for item in items">
    <option value=""> choose hall</option>
</select>

live example : http://plnkr.co/edit/iCS0blQjceA4tIIb8bUV?p=preview

Hope helps, good luck.

Comments

0

This is very common problem, when you use HTML element on*** attribute to register listeners. You have to bind controller context to listener function.

<radio onupdate="vm.save.bind(vm)" data="model.myradio1" />

I hope it will work for you.

1 Comment

You can't use bind in Angular expression. docs.angularjs.org/error/$parse/isecff

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.