angularjs: ng-src ที่เทียบเท่าสำหรับ background-image: url (…)


150

ใน angularjs คุณมีแท็ก NG-srcซึ่งมีวัตถุประสงค์ที่คุณจะไม่ได้รับความผิดพลาดสำหรับ URL ที่ไม่ถูกต้องก่อน angularjs ได้รับการประเมินผลการศึกษาตัวแปรที่อยู่ในระหว่างและ{{}}

ปัญหาคือฉันใช้ DIV บางตัวพร้อมbackground-imageชุด URL ฉันทำเช่นนี้เพราะคุณสมบัติ CSS3 ที่ยอดเยี่ยมbackground-sizeซึ่งตัดภาพให้มีขนาดที่แน่นอนของ DIV

ปัญหาเดียวคือฉันได้รับข้อผิดพลาดมากมายด้วยเหตุผลเดียวกันกับที่พวกเขาสร้างแท็ก ng-src: ฉันมีตัวแปรบางอย่างใน url และเบราว์เซอร์คิดว่าไม่มีภาพอยู่

ฉันรู้ว่ามีความเป็นไปได้ในการเขียนหยาบ{{"style='background-image:url(myVariableUrl)'"}}แต่ดูเหมือนว่า 'สกปรก'

ฉันค้นหามากและไม่สามารถหาวิธีที่ถูกต้องในการทำเช่นนี้ แอพของฉันกำลังยุ่งเพราะข้อผิดพลาดเหล่านี้ทั้งหมด

คำตอบ:


200

ngSrcเป็นคำสั่งดั้งเดิมดังนั้นดูเหมือนว่าคุณต้องการคำสั่งที่คล้ายกันซึ่งปรับเปลี่ยนbackground-imageสไตล์ของ div ของ คุณ

คุณสามารถเขียนคำสั่งของคุณเองที่ทำสิ่งที่คุณต้องการ ตัวอย่างเช่น

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

ใช้งานได้ แต่เฉพาะถ้า URL รูปภาพของคุณถูกกำหนดไว้แล้วให้ใช้ @mythz answer stackoverflow.com/a/15537359/1479680เพื่อให้มี URL ที่ไม่สามารถแก้ไขได้ดีกว่า
Magico

229

อันนี้ใช้ได้สำหรับฉัน

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

22
ฉันคิดว่านี่ควรเป็นคำตอบที่ยอมรับได้ ไม่จำเป็นต้องเพิ่มคำสั่งที่กำหนดเอง
Jakob Løkke Madsen

2
ฉันเพิ่มคำตอบที่คล้ายกับคำตอบนั้นโดยใช้การแก้ไข
wiherek

1
มันสกปรกกว่าในแง่ที่ว่าคำสั่งที่เหมาะสมกับทุกที่ที่คุณต้องการพื้นหลังแบบไดนามิก คำถามที่กล่าวถึงมันรู้สึกว่าสามารถนำมาใช้ใหม่ได้น้อยลง
Christian Bonato

ไม่ทำงานใน Angular 1.5.8 มันยังคงพยายามโหลดภาพโดยimgURLไม่ได้ตั้งค่าและลองใหม่เมื่อimgURLได้รับการตั้งค่า
leroydev

สิ่งนี้ไม่ถูกต้องหากคุณมีตัวแปรพิเศษเช่น @% ใน 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
@sqren ยังเห็นนี้ถ้าคุณกำลังใช้รุ่นที่ใหม่กว่าเชิงมุม (1.1.5 ขึ้นไป): 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

รับผลลัพธ์เดียวกัน :(
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: ความแตกต่างระหว่าง $ observ และ $ watch method


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 ให้ทำงานได้ดีที่สุดในสถานการณ์ async ของฉัน

ตัวอย่าง:

<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และดูเหมือนว่าคุณต้องการให้หน้าเสร็จสิ้นการแสดงผลก่อนที่จะโหลดภาพของคุณคุณอาจแก้ไขคำตอบของไจ๋เพื่อเรียกใช้คำสั่งพื้นฐานหลังจากเบราว์เซอร์เสร็จสิ้นการแสดงผล

โพสต์บล็อกนี้อธิบายค่อนข้างดี โดยพื้นฐานแล้วคุณต้องใส่$timeoutwrapperไว้window.setTimeoutก่อนหน้าฟังก์ชันการเรียกกลับที่ซึ่งคุณทำการแก้ไข CSS

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.