Angular Custom Directives: Calling a Function with Arguments from a Link Function

I am creating a list of clickable options that are filtered by input using a custom directive.

HTML:

<combobox 
    input-model="myModel" 
    options="myList" 
    option-label="label"
    option-select="selectFn()"></combobox>

      

Directive (simplified):

app.directive("combobox", function() {
    return {
        restrict: "E",
        replace: true,
        template: "<input type=‘text’ ng-model=‘inputModel’ />" +
                      "<button ng-repeat='option in options | " +
                                         "filter: inputModel’" +
                              "ng-mousedown=‘optionSelected(option)’" +
                      ">{{option[optionLabel]}}</button>",
        scope: {
            inputModel: "=",
            options: "=",
            optionLabel: "@",
            optionSelect: "&"
        },
        link: function(scope, elem, attrs) {
            scope.optionSelected  = function(option) {
                // some stuff here...
                scope.optionSelect();
            }
        }
    }
})

      

Application area:

$scope.myList = [
    { label: "First Option", value: 1 },
    { label: "Second Option", value: 2 },
    { label: "Second Option", value: 2 }
]
$scope.selectFn() = function() {
    // doing stuff here...
}

      

But I want to call selectFn with properties from the option that called it. Something like:

option-select="selectFn(option.value)"

      

or

scope.optionSelect(option);

      

Is it possible? Is it possible to call a function in scope and pass arguments from the reference function?

For customization reasons, I cannot use a combo box library like ui-select.

+3


source to share


2 answers


You are passing the result to the function computed in the parent scope instead of the function itself. You can evaluate your expression and then execute the resulting function.

So what you should try is

<combobox 
    input-model="myModel" 
    options="myList" 
    option-label="label"
    option-select="selectFn">

      

in your markup and then in your directive

    link: function(scope, elem, attrs) {
        scope.optionSelected  = function(option) {
            // some stuff here...
            scope.optionSelect()(option);
        }
    }

      



Note that the expression in option-select="selectFn"

will be passed to your selection area wrapped in a function optionSelect

. When you evaluate it, you get the function you want. This is why you are usingscope.optionSelect()(option)

See my directive working here: http://plnkr.co/edit/zGymbiSYgnt4IJFfvJ6G

From https://docs.angularjs.org/api/ng/service/$compile

& or & attr - Provides a way to execute an expression in a parental scope context. If attr is not specified, the attribute name is assumed to be the same as the local name. Defined and visible scope definition: {localFn: '& myAttr'}, then isolating the scope property localFn will point to the function wrapper for the expression count = count + value. It is often desirable to transfer data from the enclosed space via an expression to the parent scope, this can be done by going through the local variable names and values ​​map into the fn expression wrapper. For example, if the expression is an increment (amount), then we can specify the amount value by calling localFn as localFn ({amount: 22})

+1


source


In your directive, you should call it like this:

scope.optionSelect({
    data: []
});

      

Your template (the object will be an object with an array of data):



option-select="functionToCall(object)"

      

Then in your controller:

$scope.functionToCall = function(object){
    console.log(object);
    //will output: []
}

      

+1


source







All Articles