Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

I have a main directive that has an array on it's scope that contains data for constructing other directives that should be compiled and appended to the main directive.

The problem is that when I iterate through that array I only get the data from the last element in array, so I can't properly bind respective data for each custom directive.

Plunker

main directive :

 angular.module('testApp')
   .directive('mainDirective', ["$compile", function ($compile) {

    return {
       template:   ' <div><p>Main Directive </p><div class="insertion-point"></div></div>',

       link: function (scope, element, attributes, controller) {

          var insertionPoint = element.find('.insertion-point');

          angular.forEach(scope.demoObj.panels, function (value, index) {


              var directiveName = value.type;

              scope.value = value;
              var directiveString = "<div " + directiveName + " panel-data=value ></div>";

              var compiledElement = $compile(directiveString)(scope);

              insertionPoint.append(compiledElement);

        });
    }


    }


}]);

directive to be nested:

 angular.module('testApp')
 .directive('nestedDirective', [function () {

    return {

       scope:{
         panelData:'='
       },
       template:' <div><p>Nested Directive </p>{{panelData.data.test}}</div>'
    }
}]);

data looks like this:

                  $scope.demoObj = {

              panels:[
                {
                    id:'unique_id_1',
                    type:'nested-directive',
                    data:{
                      test:'test 1'
                    }
                },
                {
                    id:'unique_id_2',
                    type:'nested-directive',
                    data:{
                      test:'test 2'
                    }
                },
                {
                    id:'unique_id_3',
                    type:'nested-directive',
                    data:{
                      test:'test 3'
                    }
                }

            ]
        }

As far as I can understand , the compilation is not happening immediately in the forEach statement, that's why every directive gets the data from the object with the id unique_id_3 (last element in array). Also all directives have isolated scope.

edit: I understand that in forEach I need to add the value to the scope so I can pass it to the nested directive isolated scope, and I understand that when the loop finishes scope.value will be the last value of the loop, but I was under the impression that compile will immediately pass the value to the nested directive and be done with it.

So, when does the compilation happen?

How can I circumvent this limitation?

share|improve this question
    
One thing: jqLite find is limited to tag names, so you might have a problem with your insertionPoint. Also, there are errors in your data object (e.g. missing quotes and unnecessary semicolons). Are the typos in pseudocode? Or are they problems in your real code too? –  Marc Kline yesterday
    
I have jQuery present on the page. Appending elements to main directive is not a problem. –  Ivan V. yesterday
    
Can you please setup a Plunker demonstrating the issue? I tried to for you, but there are too many issues with the code you've presented. –  Marc Kline yesterday
    
@MarcKline I've created the plunker and updated the question to reflect that. –  Ivan V. 15 hours ago
    
I think your problem may have morphed based on the changes you made to your question code and Plunker, but, in any case, it seems that @YeLiu provides a working solution –  Marc Kline 14 hours ago
add comment

1 Answer

The problem is the link step of the compiledElement will happen in the next digest cycle, at that time, scope.value is the last value of the data.

The solution is to create different value properties on scope, like this:

var directiveName = value.type;
var valueProp = 'value' + index;
scope[valueProp] = value;
var directiveString = "<div " + directiveName + " panel-data=" + valueProp + "></div>";

plunk

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.