Comment imbriquer deux directives sur le même élément dans AngularJS?

Lorsque j'essaie d'imbriquer deux directives sur le même élément, j'obtiens l'erreur suivante. directives "E" imbriquées-directives multiples [...] Demander une nouvelle portée / isolée , Je veux imbriquer deux directives" E " isolées, comme dans ce violon . (Pour reproduire réellement le problème, vous devez décommenter la directive )

Je continue à avoir cette erreur que je ne comprends pas/sais comment corriger:

Error: [$compile:multidir] Multiple directives [lw, listie] asking for new/isolated scope on: <listie items="items items">

N'était-ce pas censé fonctionner? Merci!

31
demandé sur Rishabh 2013-12-16 15:26:38

7 réponses

Supprime remplacer: true sur la directive par nom "ol' ..

Cela devrait aussi résoudre .

Mise à Jour de violon : mise à jour de violon

app.directive('lw', function(){
    return {
        restrict: 'E',
        scope: {
            items: "="
        },
        template: '<listie items="items"></listie>',
        controller: function($scope) {
        }
    }
});

Analyse :

Qu'est-ce qui a causé le problème ?

Avec replace=true pour la directive lw ce qui se passe est que lw a une portée isolate, maintenant comme replace=true, l'élément remplacé qui a lui-même une portée isolate a été essayé d'être remplacé, donc ce que vous avez fait inconsciemment est que vous avez essayé de donner deux étendues pour le même élément listie.

Observation de niveau de Code en angulaire.version js 1.2.1:

Ligne 5728: function applyDirectivesToNode est la fonction qui exécute la compilation sur la directive et ici à la ligne 5772, ils vérifient si nous essayons d'attribuer une portée en double ou en d'autres termes le même élément avec deux portées .

function assertNoDuplicate(what, previousDirective, directive, element) {
      if (previousDirective) {
        throw $compileMinErr('multidir', 'Multiple directives [{0}, {1}] asking for {2} on: {3}',
            previousDirective.name, directive.name, what, startingTag(element));
      }
    }

Ci-dessus est la fonction qui fait cette vérification et si dans le cas où il y a une tentative d'attribuer deux étendues au même élément, elle lance cette erreur . Donc, c'est comme ça qu'il est conçu pour être et non un bug .

Pourquoi remplacer:vrai suppression résout le problème ?

En supprimant replace: true ce qui s'est passé est au lieu de la nouvelle directive listie remplacée au lieu de lw, elle y a été ajoutée , donc c'est une portée isolée imbriquée dans une autre, ce qui est absolument correct et autorisé . la portée d'isolat imbriquée est comme

<lw items="items" class="ng-isolate-scope">
   <div items="items" class="ng-isolate-scope">
        ..........
   </div>
</lw>

Pourquoi l'emballage dans un div fonctionnera également (c'est votre solution que vous avez considérée comme solution de contournement) ?

Le point à noter est que le div n'est pas un élément avec une portée isolate séparée .c'est juste un élément. ici, sur replace, vous attachez la portée isolate de lw à attacher à un div . (NOTE: le div en lui-même n'a pas de portée d'isolement), il n'y a donc pas de 2 portées d'isolement attachées au même élément div . il n'y a donc pas de duplication, donc l'étape d'assert est passée et elle a commencé à fonctionner .

Voici donc comment il est conçu pour fonctionner et certainement ce n'est pas un bogue .

60
répondu Harish Kayarohanam 2013-12-16 16:59:49

Juste pour des raisons d'intérêt, j'ai eu la même erreur. Il s'est avéré parce que j'ai fait l'ancien "couper et Coller" pour créer une nouvelle directive et ils avaient le même nom pour commencer. J'ai oublié de le changer ce qui a produit cette erreur.

Donc, pour tous ceux qui sont aussi mauvais que moi, voici une solution possible à vérifier.

11
répondu Stanley_A 2014-04-30 10:43:12

J'ai réussi à le réparer en remplaçant le code du modèle dans la directive wrapper. Voici la mise à jour fiddle . C'est ce qui a changé.

template: '<div><listie items="items"></listie></div>',
//template: '<listie items="items"></listie>', bug?

Cela résout mon problème, mais cela ressemble à un bug pour moi. Je suppose que je vais créer un problème sur Github.

Y - https://github.com/angular/angular.js/issues/5428

5
répondu Tony Lâmpada 2013-12-16 13:56:33

Mon problème était parce que j'incluais le fichier directive js deux fois

4
répondu ibrabeicker 2014-12-30 13:20:59

J'utilisais L'exemple Avengers et après la mise à jour à angular 1.4 j'ai commencé à obtenir ceci. En fin de compte, il y avait un contrôleur et une directive luttant pour la portée sur la même ligne

   <div my-directive ng-controller="myController as vm"></div>

Donc déplacé le contrôleur à une portée séparée pour le réparer.

<div my-directive >
<div ng-controller="myController as vm">
</div>
</div> 
3
répondu Illuminati 2015-06-11 07:37:16

La réponse acceptée ici résolu le problème pour moi.

Supprimez essentiellement la portée isolée de la directive et transmettez plutôt la propriété scope via la fonction link de la directive (dans le paramètre attributes).

0
répondu blomster 2017-05-23 12:33:21

Dans mon cas, j'avais une directive Bootstrap-ui accordion-group sur un élément qui avait ng-repeat:

<accordion-group is-open="status.open" ng-repeat="receipt in receipts">

Et résolu en faisant ceci:

<div ng-repeat="receipt in receipts">
    <accordion-group is-open="status.open">
0
répondu Julian Mann 2015-11-04 22:02:10