angularjs:ng-src等效于background-image:url(…)


150

在angularjs中,您具有标记ng-src,其目的是在angularjs评估介于{{和之间的变量之前,不会收到无效网址的错误}}

问题是,我使用了很多DIV,并将其background-image设置为url。我之所以这样做,是因为CSS3具有出色的属性background-size,可以将图像裁剪为DIV的确切大小。

唯一的问题是,由于创建ng-src标记的原因完全相同,因此我收到很多错误:我的url中有一些变量,浏览器认为该图像不存在。

我意识到有写粗略的可能性{{"style='background-image:url(myVariableUrl)'"}},但这似乎是“肮脏的”。

我搜索了很多内容,却找不到正确的方法。由于所有这些错误,我的应用变得一团糟。

Answers:


200

ngSrc是本机指令,因此似乎您想要一个类似的指令来修改div的 background-image样式。

您可以编写自己的指令来实现您想要的功能。例如

app.directive('backImg', function(){
    return function(scope, element, attrs){
        var url = attrs.backImg;
        element.css({
            'background-image': 'url(' + url +')',
            'background-size' : 'cover'
        });
    };
});​

您将这样调用

<div back-img="<some-image-url>" ></div>

JSFiddle,还有可爱的猫咪作为奖励:http//jsfiddle.net/jaimem/aSjwk/1/


67
非常好的指令;唯一的问题是它不支持插值。我可能会这样修改它:jsfiddle.net/BinaryMuse/aSjwk/2
Michelle Tilley

1
谢谢,没有插值也没关系,它有小猫!
Visgean Skeloru

如果从不受信任的来源进行加载,是否存在任何安全问题?
Aakil Fernandes

这有效,但仅当您已定义图像网址时,才使用@mythz answer stackoverflow.com/a/15537359/1479680获得更好的可见网址
Magico

229

这个对我有用

<li ng-style="{'background-image':'url(/static/'+imgURL+')'}">...</li>

22
我认为这应该是公认的答案。无需添加自定义指令。
JakobLøkkeMadsen 2014年

2
我添加了一个类似于该答案的答案,只是使用了插值法
wiherek

1
在需要动态背景的任何地方,指令都适合所有人,这更脏。提到的问题认为它的可重用性较差。
克里斯蒂安·博纳托

在Angular 1.5.8中不起作用,它仍然尝试加载imgURL未设置的图像,并在imgURL设置后重试。
leroydev '16

这是不正确的,如果您的URL中有任何特殊变量(如@%),它将中断。
efwjames

69

上面的答案不支持可观察的插值(并且花了我很多时间进行调试)。该的jsfiddle链接在@BrandonTilley意见是对我工作的答案,我将重新发布这里保存:

app.directive('backImg', function(){
    return function(scope, element, attrs){
        attrs.$observe('backImg', function(value) {
            element.css({
                'background-image': 'url(' + value +')',
                'background-size' : 'cover'
            });
        });
    };
});

使用控制器和模板的示例

控制器:

$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];

范本:

像这样在模板中使用:

<div back-img="img/service-sliders/{{someID}}/1.jpg"></div>

或者像这样:

<div ng-repeat="someID in arrayOfIDs" back-img="img/service-sliders/{{someID}}/1.jpg"></div>

40

也可以使用以下方法执行以下操作ng-style

ng-style="image_path != '' && {'background-image':'url('+image_path+')'}"

不会尝试获取不存在的图像。


2
如果您使用的是较新版本的Angular(1.1.5及更高版本),@ sqren也会看到此信息:stackoverflow.com/a/12151492/1218080。支持在视图中的实际三元运算符。
全息原理

像这样的简单字符串连接对我作用域对象,而不是插值。
Shardul

25

与hooblei的答案类似,只是内插法:

<li ng-style="{'background-image': 'url({{ image.source }})'}">...</li>

1
它在这里无效:<span ng-style="{'background-image': 'url(/styles/images/profile.png)'}" style="background-image: url("");"></span>。@hooblei方法有效。
Marcos Lima 2015年

得到相同的结果:(
Kushal Jayswal

9

只是一个口味问题,但是如果您喜欢直接访问变量或函数,如下所示:

<div id="playlist-icon" back-img="playlist.icon">

而不是像这样插值:

<div id="playlist-icon" back-img="{{playlist.icon}}">

那么您可以对指令进行一些不同的定义,scope.$watch这将对$parse属性进行

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'
            });
        });
    };
})

这里有更多背景信息:AngularJS:$ observe和$ watch方法之间的区别


2

@jaime您的回答很好。但是,如果您的页面具有$ http.get,则可以使用ng-if

app.directive('backImg', function(){
    return function($scope, $element, $attrs){
        var url = $attrs.backImg;
        $element.css({
            'background-image': 'url(' + url + ')',
            'background-size': 'cover'
        });
    }
});

在工厂里

app.factory('dataFactory', function($http){
    var factory = {};
    factory.getAboutData = function(){
        return $http.get("api/about-data.json");
    };
    return factory;
});

在控制器区域

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
        };
    });
});

如果您使用ng-if(如下所示),则将通过插值获取图像,否则将无法获取图像,因为伪指令在HTTP请求之前获取了值。

<div class="stat-banner"  ng-if="banner.image" background-image-directive="{{banner.image}}">

1

我发现1.5组件可以从DOM中抽象出样式,从而在我的异步情况下发挥最佳效果。

例:

<div ng-style="{ 'background': $ctrl.backgroundUrl }"></div>

在控制器中,如下所示:

this.$onChanges = onChanges;

function onChanges(changes) {
    if (changes.value.currentValue){
        $ctrl.backgroundUrl = setBackgroundUrl(changes.value.currentValue);
    }
}

function setBackgroundUrl(value){
    return 'url(' + value.imgUrl + ')';
}

0

既然您已经提到过ng-src,并且好像您希望页面在加载图像之前完成渲染,则可以在浏览器完成渲染之后修改jaime的答案以运行本机指令。

这篇博客文章对此做了很好的解释。本质上,您在回调函数之前插入$timeout包装器window.setTimeout在其中对CSS进行了这些修改。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.