jonnie
jonnie

Reputation: 12690

How do I use the '&' correctly when binding in a directive in Angularjs?

I have having trouble with understanding the & option in binding scope properties. I have read these tutorials: angularjs-directives-using-isolated-scope-with-attributes, practical-guide-angularjs-directives and the-hitchhikers-guide-to-the-directive as well as looking at the documentation but I am completely confused about how to use the & symbol.

Here is my attempt at using it:

var app = angular.module('directivesApp');
app.directive('simplyIsolated', function () {
    return{
        restrict: 'EA',
        replace: true,
        scope:{
            attnum: '@numone'
            ,bindnum: '=numtwo'
            ,expressnum: '&sq'
        },
        link: function (scope, elem, attr){
           scope.x = scope.expressnum();
        },
        template:'<div><p> using "@" = {{attnum+attnum}}</p>'+
                        '<p>using "=" {{bindnum+bindnum}}</p>'+
                        '<p>using "&" {{x}}</p><br/><p>{{y}}</p>'+
                '</div>'

    };

}) 
.controller('MainCtrl', function ($scope) {

    $scope.sqr = function(num){
        return num*num;
    }

});

and this is my html

<div class="container" ng-controller="MainCtrl">
    <input type="text" ng-model="num1parent" />
    <input type="number" ng-model="num2parent" />
    <input type="number" ng-model="num3parent" />
    <p>Parent Scope @ {{usernameparent}}, 
        = {{userageparent}}, 
        & = {{sqr(num3parent)}}
    </p>
    <div simply-isolated numone='{{num1parent}}' numtwo='num2parent' sq="sqr"></div>
</div>

This is the result. enter image description here the first two inputs are used to show the difference between @ and =. The third input is used to show the sqr() method works but in the text underneath the using "&" is supposed to be the square of the 2nd input but I don't get any result or error

If someone could point me in the right direction I would really appreciate it

Also: Why would you use the & over scope.$parent?

Upvotes: 0

Views: 46

Answers (1)

ryeballar
ryeballar

Reputation: 30098

Simply because you're not using the function scope.x as a function instead you have it evaluated as a mere function expression with no argument value.

try changing the template to this:

template:'<div><p> using "@" = {{attnum+attnum}}</p>'+
  '<p>using "=" {{bindnum+bindnum}}</p>'+
  '<p>using "&" {{x(bindnum}}</p><br/><p>{{y}}</p>'+
'</div>'

that should show something when you provide changes in the num2parent model.

Why would you use the & over scope.$parent?

Because it is normally not recommended to do so, if you would be doing it in such a manner it might be better not to isolate the scope of your directive and have direct access to the parent controllers properties in the directive.

Update:

The reference passed by the attribute notiation '&' is a function that returns the function defined in your controllers. To invoke the function reference, simply do this:

{{expressnum()(bindNumb)}}

that will do the trick. Note: There is a reason for this, functions often passed via '&' attribute notations are function callbacks such as events. So if your exressnum() was an callback function for an event then it would have been used like this in you template perhaps

<a ng-click="expressnum()">Click Expression</a>

Furthermore, the function sqr() is a type of function that changes the result of an expression, such functions must be defined as a filter.

Upvotes: 1

Related Questions