0

In Angular (v1.3) how do you bind the variable from an ng-repeat to a custom directive?

All the examples seem to bind to a $scope variable instead. eg given a list of products and a custom directive called product, how can we do something to this effect:

<li ng-repeat="product in products">
    <product item="product" />
</li>

Where the directive is created as:

(function () {
    'use strict';

    var productDirective = function () {
        return {
                restrict: 'E',
                scope: {item: '='},
                templateUrl: '/views/product.html',                 
            };
    };

    angular
        .module('myApp')
        .directive('product', productDirective);

})();

And it has a very simple template:

<p>{{item.name}} {{item.price}}</p>

This fails because scope: '=' only binds to $scope, not to ng-repeat.

I was able to get it to work with

return {
            restrict: 'E',
            scope: {item: '@'},
            templateUrl: '/views/product.html',

            link: function(scope, element, attributes){
                scope.item = scope.$eval(attributes.item);
            }
        };

But the usage of $eval is not really acceptable of course (bad style).

What is the correct angular way to achieve this?

3 Answers 3

1

This fails because scope: '=' only binds to $scope, not to ng-repeat.

I don't quite understand what you mean by the above, but the = in the bindings context is useful when you bind an object from the parent scope of the directive - which is in fact the controller where you have used the product directive - to the isolated scope of the directive, and NOT the ng-repeat.

Therefore, in your case, you don't actually need to bind an object from a parent controller, to the directive's isolated scope with the $eval trick.

Just make sure that in the particular parent controller you have defined the array of products properly.

Here's a Demo of how you can get it working.

Sign up to request clarification or add additional context in comments.

Comments

1

This fails because scope: '=' only binds to $scope, not to ng-repeat.

It should NOT fail because ng-repeat creates a scope for every iteration and puts the current product to it along with the other loop vars like $index. So, the product is actually on the scope and you can bind to it normally.

I created a FIDDLE with no changes to your code to confirm this.

Comments

0

Try adding a controller to the productDirective:

 var productDirective = function () {
    return {
            restrict: 'E',
            scope: {item: '='},
            templateUrl: '/views/product.html',
            controller: ['$scope', function($scope) {}]
        };
 };

2 Comments

What does that do? It hasn't made a difference, the template is not binding and still displays blank.
I created a plnkr to demonstrate: plnkr.co/edit/t2CVoeUCz8WEy1UhR9J5?p=preview

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.