【问题标题】:angularjs: ng-src equivalent for background-image:url(...)angularjs: ng-src 等价于 background-image:url(...)
【发布时间】:2012-11-26 17:30:01
【问题描述】:

在 angularjs 中,您有 tag ng-src,其目的是在 angularjs 评估放置在 {{}} 之间的变量之前,您不会收到无效 url 的错误。

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

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

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

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

【问题讨论】:

    标签: css angularjs


    【解决方案1】:

    @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}}">
    

    【讨论】:

      【解决方案2】:

      我发现 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 + ')';
      }
      

      【讨论】:

        【解决方案3】:

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

        【讨论】:

          【解决方案4】:

          只是个人喜好问题,但如果您更喜欢像这样直接访问变量或函数:

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

          而不是像这样插值:

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

          然后您可以使用 scope.$watch 稍微不同地定义指令,这将在 属性

          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

          【讨论】:

            【解决方案5】:

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

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

            【讨论】:

              【解决方案6】:

              类似于 hooblei 的回答,只是插值:

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

              【讨论】:

              • 这里不起作用:&lt;span ng-style="{'background-image': 'url(/styles/images/profile.png)'}" style="background-image: url("");"&gt;&lt;/span&gt;。 @hooblei 方法奏效了。
              • 得到相同的结果 :(
              【解决方案7】:

              ng-style 也可以这样做:

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

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

              【讨论】:

              • @sqren 如果您使用的是较新版本的 Angular(1.1.5 及更高版本),也会看到这一点:stackoverflow.com/a/12151492/1218080。添加了对视图中实际三元运算符的支持。
              • 像这样的简单字符串连接在范围对象上对我有用,而不是插值。
              【解决方案8】:

              这个适合我

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

              【讨论】:

              • 我认为这应该是公认的答案。无需添加自定义指令。
              • 我添加了一个类似的答案,只是使用插值
              • 它更脏,从某种意义上说,指令适用于所有需要动态背景的地方。问题提到它感觉不太可重用。
              • 在 Angular 1.5.8 中不起作用,它仍会尝试加载未设置 imgURL 的图像,并在设置 imgURL 时重试。
              • 这是不正确的,如果你的 URL 中有 @% 之类的特殊变量,它就会中断。
              【解决方案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/

              【讨论】:

              • 非常好的指令;唯一的问题是它不支持插值。我可能会这样修改它:jsfiddle.net/BinaryMuse/aSjwk/2
              • 谢谢,没插值没关系,有小猫!
              • 如果您从不受信任的来源加载,是否存在任何安全问题?
              • 这行得通,但前提是你的图片 url 已经定义,使用 @mythz answer stackoverflow.com/a/15537359/1479680 有一个更好的可观察的 url
              猜你喜欢
              • 1970-01-01
              • 2019-04-30
              • 2018-09-29
              • 2021-12-19
              • 1970-01-01
              • 2013-08-16
              • 1970-01-01
              • 2020-03-07
              相关资源
              最近更新 更多