angularjs: ng-src équivalent en arrière-plan-image: url(…)
dans angularjs vous avez le étiquette ng-src qui a le but que vous ne recevrez pas une erreur pour une url invalide avant angularjs obtient d'évaluer les variables placées entre {{
et }}
.
le problème est que j'utilise beaucoup de DIV avec un background-image
défini à une url. Je fais cela en raison de l'excellente propriété CSS3 background-size
qui cultive l'image à la taille exacte de la DIV.
Le seul problème est que je reçois beaucoup d'erreurs pour la même raison qu'ils ont créé une balise ng-src: j'ai quelques variables dans l'url et le navigateur pense que l'image n'existe pas.
je me rends compte qu'il y a une possibilité d'écrire un brut {{"style='background-image:url(myVariableUrl)'"}}
, mais cela semble 'sale'.
j'ai beaucoup cherché et ne peut pas trouver la bonne façon de le faire. Mon application est en désordre à cause de toutes ces erreurs.
9 réponses
ngSrc
est une directive native, il semble donc que vous vouliez une directive similaire qui modifie le style background-image
de votre div.
Vous pouvez écrire votre propre directive qui fait exactement ce que vous voulez. Par exemple
app.directive('backImg', function(){
return function(scope, element, attrs){
var url = attrs.backImg;
element.css({
'background-image': 'url(' + url +')',
'background-size' : 'cover'
});
};
});
que vous invoqueriez comme ceci
<div back-img="<some-image-url>" ></div>
JSFiddle avec des chats mignons comme un bonus: http://jsfiddle.net/jaimem/aSjwk/1/
celui-ci travaille pour moi
<li ng-style="{'background-image':'url(/static/'+imgURL+')'}">...</li>
la réponse ci-dessus ne supporte pas l'interpolation observable (et me coûte beaucoup de temps à essayer de déboguer). Le jsfiddle link in @BrandonTilley commentaire était la réponse qui a fonctionné pour moi, que je vais re-post ici pour la conservation:
app.directive('backImg', function(){
return function(scope, element, attrs){
attrs.$observe('backImg', function(value) {
element.css({
'background-image': 'url(' + value +')',
'background-size' : 'cover'
});
});
};
});
exemple utilisant le contrôleur et le gabarit
contrôleur:
$scope.someID = ...;
/*
The advantage of using directive will also work inside an ng-repeat :
someID can be inside an array of ID's
*/
$scope.arrayOfIDs = [0,1,2,3];
modèle:
utiliser dans le modèle comme suit:
<div back-img="img/service-sliders/{{someID}}/1.jpg"></div>
ou similaire:
<div ng-repeat="someID in arrayOfIDs" back-img="img/service-sliders/{{someID}}/1.jpg"></div>
il est aussi possible de faire quelque chose comme ça avec ng-style
:
ng-style="image_path != '' && {'background-image':'url('+image_path+')'}"
qui ne tenterait pas de récupérer une image non existante.
semblable à la réponse de hooblei, juste par interpolation:
<li ng-style="{'background-image': 'url({{ image.source }})'}">...</li>
juste une question de goût, mais si vous préférez accéder à la variable ou à la fonction directement comme ceci:
<div id="playlist-icon" back-img="playlist.icon">
au lieu d'interpoler comme ceci:
<div id="playlist-icon" back-img="{{playlist.icon}}">
alors vous pouvez définir la directive un peu différemment avec scope.$watch
qui fera $parse
sur le
attribut
angular.module('myApp', [])
.directive('bgImage', function(){
return function(scope, element, attrs) {
scope.$watch(attrs.bgImage, function(value) {
element.css({
'background-image': 'url(' + value +')',
'background-size' : 'cover'
});
});
};
})
Il ya plus de fond sur ce ici: AngularJS: différence entre le $ observer et $ watch méthodes
@jaime votre réponse est très bien. Mais si votre page a le $http.obtenir alors vous devez utiliser ng-si
app.directive('backImg', function(){
return function($scope, $element, $attrs){
var url = $attrs.backImg;
$element.css({
'background-image': 'url(' + url + ')',
'background-size': 'cover'
});
}
});
à l'usine
app.factory('dataFactory', function($http){
var factory = {};
factory.getAboutData = function(){
return $http.get("api/about-data.json");
};
return factory;
});
dans la zone du contrôleur
app.controller('aboutCtrl', function($scope, $http, dataFactory){
$scope.aboutData = [];
dataFactory.getAboutData().then(function(response){
// get full home data
$scope.aboutData = response.data;
// banner data
$scope.banner = {
"image": $scope.aboutData.bannerImage,
"text": $scope.aboutData.bannerText
};
});
});
et la vue si vous utilisez le ng-si comme ci-dessous, vous obtiendrez l'image par interpolation sinon, vous ne pouvez pas obtenir l'image car la directive obtient la valeur avant la requête HTTP.
<div class="stat-banner" ng-if="banner.image" background-image-directive="{{banner.image}}">
j'ai trouvé avec 1.5 composants qui Abstraction le style du DOM pour mieux fonctionner dans ma situation async.
exemple:
<div ng-style="{ 'background': $ctrl.backgroundUrl }"></div>
et dans le contrôleur, quelque chose comme ceci:
this.$onChanges = onChanges;
function onChanges(changes) {
if (changes.value.currentValue){
$ctrl.backgroundUrl = setBackgroundUrl(changes.value.currentValue);
}
}
function setBackgroundUrl(value){
return 'url(' + value.imgUrl + ')';
}
puisque vous avez mentionné ng-src
et qu'il semble que vous vouliez que la page termine le rendu avant de charger votre image, vous pouvez modifier la réponse de jaime pour exécuter la directive native après le navigateur termine le rendu.
ce billet de blog explique assez bien cela; essentiellement, vous insérez le $timeout
wrapper pour window.setTimeout
avant la fonction de rappel dans laquelle vous faites ces modifications à la feuille de style CSS.