oikonomiyaki
oikonomiyaki

Reputation: 7951

Function arguments in directive with templateUrl

I created a custom directive with an isolated scope that binds to a function from the enclosing controller and with references to a templateUrl. Here's what my code looks like:

the html

<div ng-controller='MyCtrl as my'>
    <custom-directive data='my.data' on-search="my.find(param1, param2)"></custom-directive>
</div>

the directive

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

    return {
        restrict : 'E',
        scope : {
            data : '=data'
            search : '&onSearch',
        },
        templateUrl : 'customDirective.html'
    };
});

the template

<div>
    <input ng-model='data.id'>
    <a ng-click='find(param1, param2)'></a>

</div>

The arguments received by function find is also stored in data. The controller data binds to the directive but not the function. My log inside the function won't even show.

It seems there are different ways to do it as I have seen in many examples (see below) but none seems to work in my case.

Example 1: pass a mapping of parameter and values in the template

<div>
    <input ng-model='data.id'>
    <a ng-click='find.({param1: data.value1, param2: data.value2})'></a>

</div>

Example 2: put a link in the directive

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

    return {
        restrict : 'E',
        scope : {
            data : '=data'
            search : '&onSearch',
        },
        templateUrl : 'customDirective.html',
        link : function(scope, elem, attr) {
            scope.retrieve({param1: scope.data.value1,
                            param2: scope.data.value2});
        }

    };
});

Example 3 : use scope.$apply(), $parse in link but haven't tried this

Could someone show me how to do it and also explain to me the link part (I don't understand that part) and if you're feeling generous, show the working alternatives as shown by the examples. Thanks

Upvotes: 2

Views: 1604

Answers (1)

Mathieu Bertin
Mathieu Bertin

Reputation: 1624

You don't have to passe params for your function just the reference so in your html

<custom-directive data='my.data' on-search="my.find"></custom-directive>

and your template directive directly call

<div>
    <input ng-model='data.id'>
    <a ng-click='find(data.value1, data.value2)'></a>
</div>

I also suggest you to use $scope and not the controller. So in your controller define

$scope.data = {
    id: 1,
    value1: "value1",
    value2: "value2"
}

$scope.find = function (param1, param2) {
   //Your logic
}

And in your template put directly

<custom-directive data='data' on-search="find"></custom-directive>

I hope this answer to your question

About link this text from angular js doc is pretty clear I think

Directives that want to modify the DOM typically use the link option. link takes a function with the following signature, function link(scope, element, attrs) { ... } where:

scope is an Angular scope object. element is the jqLite-wrapped

element that this directive matches. attrs is a hash object with key-value pairs of normalized attribute names and their corresponding attribute values.

In our link function, we want to update the displayed time once a second, or whenever a user changes the time formatting string that our directive binds to. We will use the $interval service to call a handler on a regular basis. This is easier than using $timeout but also works better with end-to-end testing, where we want to ensure that all $timeouts have completed before completing the test. We also want to remove the $interval if the directive is deleted so we don't introduce a memory leak.

Upvotes: 2

Related Questions