web-dev-qa-db-fra.com

Plusieurs directives demandant des modèles sur

J'ai le code HTML suivant:

<div style="border:1px solid; height:300px; width:500px; position:relative;  left:100px" id="canvas">
  <tbox ng-repeat="tb in textBoxes" ng-model="tb">
  </tbox>
</div>

Et les 2 directives suivantes

appModule.directive('resizable', function($compile, $document) {
  return {
    restrict: "A",
    template: '<div ng-style="{top:tb.x, left:tb.y, height:tb.height, width:tb.width}"  ng-transclude><span class="scale">s</span></div>',
    transclude: true,
    replace: true,
    require: 'ngModel'
  }
});

appModule.directive('tbox', function($document) {
  return {
    restrict: "E",
    template: '<div class="editbox" resizable editoptions>{{tb.text}}</div>',
    replace: true
  }
});

Que signifie exactement l'erreur suivante que angular me lance?

Error: Multiple directives [tbox, resizable] asking for template on: <div class="editbox" resizable="" editoptions="" ng-repeat="tb in textBoxes" ng-model="tb">

jsfiddle à http://jsfiddle.net/sEZM3/

34
goh

Vos deux directives tentent de remplacer l'élément dans le dom. Essayez de supprimer les lignes replace: true dans votre objet de définition de directive.

29
Jason

La même erreur peut se produire si vous essayez de charger plusieurs fois le même code de directive par erreur. Cela peut arriver surtout lorsque vous conservez chaque élément angulaire (comme une directive) dans un fichier séparé et que vous incluez chaque élément avec une ligne distincte. C'était mon cas.

24
Wojciech Majerski

Pour moi, cela était dû à plusieurs copies de la directive et du modèle existant dans le répertoire dist , causées par le grunt building sans nettoyage (pendant une tâche watch ). Un nettoyage et une reconstruction ont résolu ce problème pour moi.

12
arieljake

Pour moi, il s'agissait d'inclure deux fois la même directive dans le fichier index.html.

6
MAhsan

Pour les utilisateurs de Visual Studio utilisant TypeScript, cela me convient. J'avais renommé mon fichier TypeScript et le fichier .js construit se trouvait dans le répertoire (mais cela ne s'affiche pas dans le projet). Je devais afficher tous les fichiers du répertoire pour supprimer les fichiers * .js inutilisés persistants.

3
malckier

M'est arrivé alors que j'avais deux composants portant le même nom (erreur de copier/coller):

Pour mon coffeescript, mais facile à réaliser en pure angular:

component1.coffee
    appModule.component('name', {
    templateUrl: '/public/partials/html1.html',
  controller: 'controler1',
  bindings: {
    somebindings: '<'
  }
});


component2.coffee
    appModule.component('name', {
    templateUrl: '/public/partials/html2.html',
  controller: 'controler2',
  bindings: {
    somebindings: '<'
  }
});

Conclusion: "nom" doit être unique dans toute l'application.

2
Rafał

La directive resizable est incorrecte. La directive ng-transclude doit être appliquée à l'élément le plus interne, car son contenu sera ignoré et remplacé par du contenu transclus.

Vous devez entourer le modèle tbox directive avec (corrigé) resizable element. Je ne sais pas ce que editoptions attribut fait, mais si c'est aussi une directive, alors il ne devrait pas avoir de modèle.

Je veux dire quelque chose comme ça:

appModule.directive('resizable', function($compile, $document) {
    return {
        restrict: "E",
        template: '<div ng-style="{top:tb.x, left:tb.y, height:tb.height, width:tb.width}"  ng-transclude></div>',
        transclude: true,
        replace: true,
        //...

appModule.directive('tbox', function($document) {
    return {
        restrict: "E",
        template: '<resizable><div class="editbox" editoptions>{{tb.text}}</div></resizable>',
        replace: true,
        //...

Résultat:

<div ng-style="{top:tb.x, left:tb.y, height:tb.height, width:tb.width}"  ng-transclude>
    <div class="editbox" editoptions>{{tb.text}}</div>
</div>
2
Adam

Dans mon cas, j'avais une référence à un fichier manquant dans BundleConfig, j'ai supprimé la référence et cela a commencé à fonctionner.

1
Francisco G

Pour moi, il n'y avait pas de doublons dans mon code. Ceci est dû au fait que je duplique un module pour obtenir une longueur d’avance sur le nouveau, puis que je fasse une recherche/un remplacement à l’échelle du module et modifie les noms des fichiers.

Même s'il n'y avait plus de doublon et que j'arrêtais et démarrais le serveur basé sur browsersync, l'erreur continuait. 

La solution a été résolue en supprimant le répertoire .tmp créé par le système de construction pour l'environnement dev. 

Il est évident que le générateur FountainJS que j'utilise crée un système de construction qui laisse le répertoire .tmp sale dans certains cas, comme celui-ci. Il m'a attrapé plusieurs fois maintenant. 

1
shanemgrey

Il peut également s'agir d'une simple erreur, telle que conserver les propriétés template et templateUrl dans la même directive.

0
Rouche

(au cas où cela aiderait quelqu'un d'autre)

Pour moi, le problème était d'avoir un fichier de sauvegarde (c'est-à-dire .bkp.html) qui n'était qu'une ancienne copie d'un modèle que j'utilisais pour référence - mais cela était inclus par karma puisqu'il correspondait à ".../**/* .html ".

0
wdanda

Vous ne pouvez pas avoir une directive (élément) directement référençant une autre directive (élément). Enveloppez-le avec un <div>, par exemple:

template: '<div><my-custom-directive>'
        + '</my-custom-directive></div>'

Voir https://github.com/angular/angular.js/issues/5428 pour plus d'informations.

0
Tom Söderlund