Utilisation de ng-src vs src

89

Ce tutoriel montre l'utilisation de la directive ngSrcau lieu de src:

<ul class="phones">
    <li ng-repeat="phone in phones" class="thumbnail">
        <img ng-src="{{phone.imageUrl}}">
    </li>
</ul>

Ils demandent:

Remplacez la directive ng-src par un ancien attribut src.
À l'aide d'outils tels que Firebug ou l'inspecteur Web de Chrome, ou en inspectant les journaux d'accès au serveur Web, confirmez que l'application envoie effectivement une requête superflue à /app/%7B%7Bphone.imageUrl%7D%7D (ou / app / {{phone .imageUrl}} ).

Je l'ai fait et cela m'a donné le résultat correct:

<li class="thumbnail ng-scope" ng-repeat="phone in phones">
    <img src="img/phones/motorola-xoom.0.jpg">
</li>

Y a-t-il une raison pour laquelle?

Majid Laissi
la source

Réponses:

108
<img ng-src="{{phone.imageUrl}}"> 

Cela vous donne le résultat attendu, car il phone.imageUrlest évalué et remplacé par sa valeur après le chargement angulaire.

<img src="{{phone.imageUrl}}">

Mais avec cela, le navigateur essaie de charger une image nommée {{phone.imageUrl}}, ce qui entraîne un échec de la demande. Vous pouvez vérifier cela dans la console de votre navigateur.

Thierry
la source
Je pense qu'il va en fait essayer de charger une image comme src = "" plutôt que {{phone.imageUrl}} à la place.
Jeff Ling
2
@JeffLing non c'est en fait `{{phone.imageUrl}}` comme l'indique le tutoriel. Je n'ai pas compris que le navigateur effectue une première requête http avant le démarrage d'angularjs. Maintenant je comprends.
Majid Laissi
Salut, je pense que c'est une mauvaise solution car je faisais de cette façon pendant un moment et j'ai trouvé que cette méthode ne fonctionne pas sur les anciens navigateurs IE, donc ma recommandation est d'utiliser ng-src
imal hasaranga perera
J'ai actuellement un problème pour remplir ng-src via la directive et utiliser $ element.attr ('ng-src', this.imageSrc); .... une idée pourquoi? La valeur de l'image est correcte, je suppose que je devrais exécuter une portée. $ Apply ou digest plus tard ... mais pas d'idée où ...
Micky
126

À partir de la documentation Angular

La façon buggy de l'écrire:

<img src="http://www.gravatar.com/avatar/{{hash}}"/>

La bonne façon de l'écrire:

<img ng-src="http://www.gravatar.com/avatar/{{hash}}"/>

Pourquoi? en effet, lors du chargement de la page, avant l'amorçage angulaire et la création des contrôleurs, le navigateur essaiera de charger l'image depuis http://www.gravatar.com/avatar/{{hash}}et il échouera. Ensuite, une fois angular démarré, il comprend que cela {{hash}}doit être remplacé par disons logo.png, maintenant l'attribut src change http://www.gravatar.com/avatar/logo.pnget l'image se charge correctement. Le problème est qu'il y a 2 demandes en cours et une première échoue.

Pour résoudre ce problème, nous devons utiliser ng-srcune directive angulaire et angular remplacera la ng-srcvaleur dans l'attribut src uniquement après le démarrage angulaire et les contrôleurs entièrement chargés, et à ce moment-là, {{hash}}ils auraient déjà été remplacés par la valeur de portée correcte.

Subin Sebastian
la source
17

Le src="{{phone.imageUrl}}"n'est pas nécessaire et crée une demande supplémentaire de la part du navigateur. Le navigateur fera au moins 2 GETrequêtes pour tenter de charger cette image:

  1. avant que l'expression ne soit évaluée {{phone.imageUrl}}
  2. après l'évaluation de l'expression img/phones/motorola-xoom.0.jpg

Vous devez toujours utiliser une ng-srcdirective lorsque vous traitez avec des expressions angulaires. <img ng-src="{{phone.imageUrl}}">vous donne le résultat attendu d'une seule requête.


Sur une note latérale , la même chose s'applique à ng-hrefafin que vous n'obteniez pas de liens cassés avant le début du premier cycle de résumé.

Letiagoalves
la source
0

En fait, cela a 100% de sens car le HTML est traité séquentiellement et lorsque cette page HTML est traitée ligne par ligne, au moment où elle arrive à cette image, la ligne et le traitement de l'image, notre phone.imageUrln'est pas encore défini.

Et en fait, Angular JS n'a pas encore traité ce morceau de HTML, et n'a pas encore cherché ces espaces réservés et substitué ces expressions par les valeurs. Donc, ce qui finit par arriver, c'est que le navigateur obtient cette ligne et essaie de récupérer cette image à cette URL.

Et bien sûr, il s'agit d'une fausse URL, si elle contient toujours ces moustaches et ces accolades, et par conséquent, elle vous donne un 404, mais une fois que bien sûr Angular s'en occupe, il remplace cette URL par la bonne, puis nous voyons toujours l'image, mais pourtant le message d'erreur 404 reste dans notre console.

Alors, comment pouvons-nous nous en occuper? Eh bien, nous ne pouvons pas nous en occuper en utilisant des astuces HTML classiques. Mais nous pouvons nous en occuper en utilisant Angular. Nous devons d'une manière ou d'une autre dire au navigateur de ne pas essayer de récupérer cette URL, mais en même temps de la récupérer uniquement lorsque Angular est prêt pour l'interprétation de ces espaces réservés.

Eh bien, une façon de le faire est de mettre un attribut Angular ici au lieu de l'attribut HTML standard. Et l'attribut angulaire est juste ng-src. Donc, si nous disons cela maintenant, revenez en arrière, vous verrez qu'il n'y a plus d'erreurs car l'image n'a été récupérée qu'une fois qu'Angular a mis la main sur ce HTML et traduit toutes les expressions dans leurs valeurs.

Divyanshu Rawat
la source