0

J'ai un main directive qui a un array sur son champ qui contient des données pour la construction d'autres directives qui devrait être compilé et annexé au main directive. Le problème est que lorsque je parcourt ce tableau, je ne reçois que les données du dernier élément du tableau, , donc je ne peux pas lier correctement les données respectives pour chaque directive personnalisée.créer Dynamiquement directives d'une boucle

Plunker

directive principale:

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

à imbriquée:

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

    return { 

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

ressemble à ceci:

    $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' 
        } 
       } 

      ] 
     } 

En ce que je peux en stand, la compilation ne se produit pas immédiatement dans l'instruction forEach, c'est pourquoi chaque directive obtient les données de l'objet avec l'ID unique_id_3 (dernier élément dans le tableau). Toutes les directives ont également une portée isolée.

edit: Je comprends que forEach je dois ajouter la valeur à la portée pour que je puisse pass à la directive imbriquée champ isolé, et je comprends que lorsque la boucle se termine scope.value sera le dernier value de la boucle, mais j'étais sous l'impression que la compilation immediately passera la valeur à la directive imbriquée et sera fait avec elle.

Alors, quand la compilation a-t-elle lieu?

Comment contourner cette limitation?

+0

Une chose: jqLite 'find' est limité à marquer les noms, vous pourriez avoir un problème avec votre' insertionPoint'. En outre, il existe des erreurs dans votre objet de données (par exemple, des guillemets manquants et des points-virgules inutiles). Les fautes de frappe dans le pseudocode? Ou sont-ils des problèmes dans votre vrai code aussi? –

+0

J'ai jQuery présent sur la page. L'ajout d'éléments à la directive principale n'est pas un problème. –

+0

Pouvez-vous s'il vous plaît configurer un [Plunker] (http://plnkr.co/) démontrant le problème? J'ai essayé de le faire pour vous, mais il y a trop de problèmes avec le code que vous avez présenté. –

Répondre

2

Le problème est l'étape de liaison de la compiledElement se produira dans le cycle digérer suivant, à ce moment-là, scope.value est la dernière valeur des données.

La solution est de créer des propriétés de valeur différentes sur la portée, comme ceci:

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

plunk

1

S'il vous plaît trouver le code de mise à jour ci-dessous. Plutôt que de créer une variable en double dans la portée Voici la solution. J'ai créé plunker pour la même

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; 
      var directiveString = "<div " + directiveName + " panel-data=demoObj.panels["+ index+"]></div>"; 

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

      insertionPoint.append(compiledElement); 
    }); 
} 
} 
}]);