Bonjour, j'ai découvert il n'y a pas très longtemps les tutos Grafikart. Ils parcourent les domaines étudiés de manière complète sans entrer dans les détails perturbnant pour le débutant.
Je débute avec Angular et je bloque sur le tuto concernant créer ses directives :
A 10:19, il est expliqué que l'on peut nommer comme on veut l'attribut du scope lolcava.
J'ai suivi le tuto, installé Batarang pour vérifier le scope mais je n'arrive pas à afficher le contenu lorsque je change le nom de l'attribut :

Dans app.js

app.directive('ngComment', function(){
    return {
        templateUrl : 'partials/_comments.html',
        restrict : 'E',
        scope : {
            lolcava : '=comment'
        }
    };
});

dans comments.html

<div ng-repeat="comment2 in comments">
    <ng-comment comment="comment2"></ng-comment>
</div>

et dans partials/_comments.html

<p><strong>{{comment.username}} :</strong><br>{{comment.content}}</p>

Au niveau du Batarang j'ai bien le contenu qui apparaît au niveau de chaque scope de la boucle, donc a priori ça fonctionne, mais rien ne s'affiche à l'écran dans le html

Par contre si je mets

app.directive('ngComment', function(){
    return {
        templateUrl : 'partials/_comments.html',
        restrict : 'E',
        scope : {
            comment : '=' //ou bien comment : '=comment'
        }
    };
});

Le contenu s'affiche.

Quel peut être le problème ?
PS :

  • J'utilise la dernière version d'Angular (1.2.26)
  • Avec l'exemple de la doc j'ai le même problème...
  • Je n'ai pas d'erreur JS

Merci d'avance

2 réponses


Govan06
Réponse acceptée

Quand tu crée un scope isolé avec

scope : {
   lolcava : '=comment'
}

Le template de ta directive s'attend à ce que tu lui passe ce scope, sinon ça n'a pas d'intêret.
Donc dans ton partials/_comments.html :

<p><strong>{{lolcava.username}} :</strong><br>{{lolcava.content}}</p>

En mettant

app.directive('ngComment', function(){
    return {
        templateUrl : 'partials/_comments.html',
        restrict : 'E',
        scope : {
            comment : '=' //ou bien comment : '=comment'
        }
    };
});

Cela marche effectivement, car tu as créé un <u>nouveau</u> scope comment et ta directive utilise ce scope.

Ah et ça n'a rien à voir avec le problème, mais il faut éviter de préfixer ses directives avec 'ng' car cela pourra générer des collisions avec les futures versions d'angular (imagine dans angular 2.0 ils intégrent une directive ngComment).

Depuis la doc d'angular :

" Best Practice: In order to avoid collisions with some future standard, it's best to prefix your own directive names. For instance, if you created a <carousel> directive, it would be problematic if HTML7 introduced the same element. A two or three letter prefix (e.g. btfCarousel) works well. Similarly, do not prefix your own directives with ng or they might conflict with directives included in a future version of Angular. "

source

Edit: pour mieux comprendre ce qui se passe : saches qu'en déclarant ta directive telle quelle, celle-ci a implicitement construit une fonction link , fonction qui est éxéctuée quand ton template a été cloné dans le dom. Elle prend, entre autre paramètre, le scope de la directive. Comme dans notre cas le scope est isolé, il aura dans ses propriétés un object qui a pour clé 'lolcava' et en valeur l'object comment passé dans la déclaration de notre directive

Un petit plunker qui illustre tout ça

http://plnkr.co/edit/PiEjRfgIuM9KLP43K0Il?p=preview

Voilà :-)

olivierd
Auteur

Merci pour cette réponse (et en plus rapide :D )
Cependant :
Le template de ta directive s'attend à ce que tu lui passe ce scope, sinon ça n'a pas d'intêret.
A aucun moment Grafikart ne le précise dans la vidéo pour cette partie (je sais, j'aurais pu tester...)

à 10:14, on voit dans son exemple que dans la page sous "2 commentaires" apparaît le premier : Horne (c'est quand il explique avec scope {content : '=' }
à 10:38, , on voit dans son exemple que dans la page sous "2 commentaires" n'apparaît plus rien (c'est quand il explique avec scope {lolcava : '=content' }

Donc on a le même résultat (le Batarang affiche bien le contenu de l'objet et rien ne s'affiche), mais il ne précise pas qu'il faut modifier dans le template. Après coup, effectivement ça parait totalement logique :D

il faut éviter de préfixer ses directives avec 'ng' oui, j'ai lu dans les commentaires de la vidéo et dans la doc qu'effectivement, il ne faut pas utiliser ng. Si je l'ai fait c'est que j'ai essayé de reproduire l'exemple du tuto dans lequel le nom de la directive est ng-.

Un petit plunker qui illustre tout ça merci beaucoup pour l'exemple.

Il semble qu'en plus de cette (petite, certes, mais perturbante) omission dans le tuto, il semblerait que le cache de mon Chrome / FF ne prenne pas en compte immédiatement les modifications, d'où multiplication des possibilités d'erreur.