Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AngularJS: how do I code an element directive with optional attribute parameters?

I'm doing my first steps in AngularJS directives. Just set up this one as an exercise to output a product name:

.directive('productname', function (Prefs) {
        return {
            restrict: 'E',
            replace: true,
            transclude: true,
            templateUrl: '/partials/productname.html',
            link: function (scope, element, attrs) {
                scope.brand = Prefs.owner;
            }
        }
    })

productname.html

<span class="productname"><span class="brand">{{brand}}</span> <span class="product" ng-transclude>{{productname}}</span></span>

and so the usage is plainly: <productname>{{product.name}}</productname>

Now, could someone tell me how I should go about making this directive configurable by adding a flag to output the productname linked?

The usage would be: <productname linked>{{product.name}}</productname> and the output/template would be:

<span class="productname"><a href="/edit/{{id}}"> <span class="brand">{{brand}}</span> <span class="product" ng-transclude>{{productname}}</span></a></span>

Seems complicated and I cannot quite figure out where the logic should be injected...

like image 740
user776686 Avatar asked Jul 03 '26 00:07

user776686


1 Answers

First of all, you should use the scope property of the directive declaration. Also, you do not need transclude in this case. Like so:

.directive('productname', function (Prefs) {
    return {
        restrict: 'E',
        scope: {
            product: "=",
            linked: "="
        },
        replace: true,
        templateUrl: '/partials/productname.html',
        link: function (scope, element, attrs) {
            // scope.product and scope.linked are automatically set
            scope.brand = Prefs.owner;
        }
    }
})

And the template:

<span class="productname" ng-switch="linked">
    <a href="/edit/{{id}}" ng-switch-when="true">
        <span class="brand">{{brand}}</span>
        <span class="product">{{product.name}}</span>
    </a>
    <span ng-switch-default>
        <span class="brand">{{brand}}</span>
        <span class="product">{{product.name}}</span>
    </span>
</span>

Call the template like so:

<productname product="product"></productname>

or:

<productname product="product" linked="'true'"></productname>

Update

If you want to use the linked attribute as a flag, you could do that by using the attrs variable:

.directive('productname', function (Prefs) {
    return {
        restrict: 'E',
        scope: {
            product: "="
        },
        replace: true,
        templateUrl: '/partials/productname.html',
        link: function (scope, element, attrs) {
            // scope.product is automatically set
            scope.linked = typeof attrs.linked != 'undefined';
            scope.brand = Prefs.owner;
        }
    }
})

Call it like so:

<productname product="product" linked></productname>
like image 139
Alp Avatar answered Jul 05 '26 16:07

Alp