首页 文章

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

提问于
浏览
148

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

问题是我使用了相当多的DIV并将 background-image 设置为url . 我这样做是因为优秀的CSS3属性 background-size 将图像裁剪为DIV的确切大小 .

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

我意识到有可能写出原油 {{"style='background-image:url(myVariableUrl)'"}} ,但这似乎是'dirty' .

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

9 回答

  • 9

    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/

  • 40

    这个对我有用

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

    上面的答案不支持可观察的插值(并且我花了很多时间尝试调试) . @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'
                });
            });
        };
    });
    

    使用控制器和模板的示例

    Controller :

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

    Template :

    在模板中使用如下:

    <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>
    
  • 0

    使用 ng-style 也可以这样做:

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

    它不会尝试获取不存在的图像 .

  • 226

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

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

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

    <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 : Difference between the $observe and $watch methods

  • 197

    @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 + ')';
    }
    
  • 68

    由于您提到了 ng-src ,似乎您希望页面在加载图像之前完成渲染,因此您可以修改jaime的答案,以便在浏览器完成渲染后运行本机指令 .

    This blog post很好地解释了这一点;实质上,您在回调函数之前插入$timeout wrapper for window.setTimeout ,其中您对CSS进行了这些修改 .

相关问题