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

时间:2012-12-08 20:36:50

标签: css angularjs

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

问题是我使用了一些DIV,background-image设置为url。我这样做是因为优秀的CSS3属性background-size将图像裁剪为DIV的确切大小。

唯一的问题是我收到很多错误的原因与他们创建ng-src标签的原因完全相同:我在网址中有一些变量,浏览器认为图片不存在。

我意识到有可能写出粗略的{{"style='background-image:url(myVariableUrl)'"}},但这看起来很“脏”。

我搜索了很多,找不到正确的方法来做到这一点。由于所有这些错误,我的应用程序变得一团糟。

9 个答案:

答案 0 :(得分:226)

这个适用于我

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

答案 1 :(得分:198)

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/

答案 2 :(得分:69)

上面的答案不支持可观察的插值(并且我花了很多时间尝试调试)。 @BrandonTilley评论中的jsFiddle link是对我有用的答案,我将在此重新发布以保存:

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>

答案 3 :(得分:40)

也可以使用ng-style执行类似的操作:

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

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

答案 4 :(得分:25)

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

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

答案 5 :(得分: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' }); }); }; }) 属性

{{1}}

此处有更多背景资料:AngularJS : Difference between the $observe and $watch methods

答案 6 :(得分: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}}">

答案 7 :(得分: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 + ')';
}

答案 8 :(得分:0)

由于您提到ng-src并且在加载图片之前似乎希望页面完成呈现,您可以修改jaime的回答以在之后运行本机指令浏览器完成渲染。

This blog post很好地解释了这一点;实质上,您在回调函数之前插入window.setTimeout {{1}},然后对CSS进行修改。