2016-04-13 2 views
3

Je viens d'ajouter un service CDN pour accélérer le chargement de mon site Web. J'ai une question concernant les photos qui sont récupérées en utilisant un tag <img>.Utilisation de CDN avec <img> Tags

J'ai bien des cas comme celui-ci:

// userProfile.thumbnailPhotoSrc = some/relative/path.png  
ng-src="{{userProfile.thumbnailPhotoSrc}}" 

(j'utiliser AngularJS). Au démarrage, j'ai un script qui enregistre le point de terminaison CDN à window.cdn variable. Dans le cas où le script décide qu'il n'y a pas point final disponible:

window.cdn = ''; 

Je veux être capable de faire quelque chose comme:

ng-src="window.cdn + {{userProfile.thumbnailPhotoSrc}" 

Mais cela est impossible, comme window.cdn n'est pas évalué. Mais ni cela fonctionne:

ng-src="{{window.cdn + userProfile.thumbnailPhotoSrc}" 

Parce que je ne peux accéder à $scope propriétés sous {{}}. Je ne peux pas enregistrer le point de terminaison CDN à $scope, car il existe un $scope pour chaque contrôleur (j'en ai beaucoup, ce n'est pas maintenable).

La dernière chose que je pensais, dans l'espoir ng-src permet que - est l'ajout d'une fonction de transformation qui est exécutée sur tout ng-src attribut, mais je ne pouvais pas trouver comment faire.

Que suggérez-vous que je fasse? gardez à l'esprit que je voudrais que le site Web récupère la photo du CDN et se replie sur le serveur d'origine (récupère le chemin relatif) en cas de dysfonctionnement du CDN. Comment puis-je obtenir ce comportement?

Merci

+0

Salut johni, comment obtenez-vous des images d'un CDN? Voulez-vous finalement atteindre un point de terminaison d'une API pour récupérer des données d'image? Aussi, juste un petit conseil - vous n'avez pas besoin du "{{}}" dans les guillemets. Parfois, cela gâche les choses. – socialpiranha

+0

J'utilise le même chemin relatif que ce 'userProfile.thumbnailPhotoSrc' détient juste avec un domaine différent. Par exemple: '' https://blabla.cdn.com/ '+ {{userProfile.thumbnailPhotoSrc}} '- serait évalué à la bonne adresse du CDN. – johni

+0

Je pense que cela pourrait aider: http://stackoverflow.com/questions/11938380/global-variables-in-angularjs – Hoyen

Répondre

4

Vous pouvez créer un custom filter dans angulaire

alors que vous auriez alors dans vos modèles:

ng-src="{{userProfile.thumbnailPhotoSrc | cdn}" 

Vous pouvez ajouter le service $window comme une dépendance au service de filtre afin vous n'avez pas à le retirer de l'objet global et vous pouvez également tester le filtre.

+0

C'est gentil, je n'étais pas au courant de cela mais que faire si j'ai 1000 étiquettes ? Je dois passer en revue tout cela. Je cherche un moyen d'éviter cela. – johni

+0

@johni - Sûrement de la même manière que vous le feriez avec 1000 tags img si vous ne vouliez pas les pousser à travers le filtre? – Quentin

1

Si vous essayez de mettre à jour tous les src <img>. Vous pouvez créer une directive:

angular.module('imageCdnSrc', []) 
.directive('img',['$interpolate', function($interpolate) { 
    return { 
    restrict: 'E', 
    scope: false, 
    compile: function(element, attrs) { 
     var ngSrc = attrs.ngSrc; 
     delete attrs.ngSrc; // prevent ngSrc directive to trigger 

     return function($scope,element,attrs) { 
     var ngSrcVal = $interpolate(ngSrc)($scope); //returns the string value of ngSrc 

     /* Add Logic Below to decide what to do */ 
     if(window.cdn && ngSrcVal && ngSrcVal.length>0){ 
      attrs.ngSrc = window.cdn + ngSrcVal; 
      /* if image fails to load with cdn, load the default */ 
      element.one('error', function() { 
      angular.element(this).attr("src", ngSrcVal); 
      }); 
     } 
     else{ 
      attrs.ngSrc = ngSrcVal; 
     } 
     };  
    } 
    }; 
}]); 
+0

Qu'est-ce qui rend cette exécution avant le rappel de '$ observer' de la directive ngSrc? – johni

+0

@johni Ok j'ai mis à jour avant de compiler il ajoutera window.cdn au ngSrc – Hoyen

+0

Dans les cas où 'ng-src =" {{userProfile.thumbnailPhotoSrc}} '' la fonction de compilation de la directive est appelée avant le '{{ }} 'est évalué. – johni