angularjs: ekuivalen ng-src untuk background-image: url (...)

150

Di angularjs Anda memiliki tag ng-src yang bertujuan agar Anda tidak akan menerima kesalahan untuk url yang tidak valid sebelum angularjs mengevaluasi variabel yang ditempatkan di antara {{dan }}.

Masalahnya adalah bahwa saya menggunakan beberapa DIV dengan background-imageset ke url. Saya melakukan ini karena properti CSS3 yang sangat baik yang memotong background-sizegambar ke ukuran persis DIV.

Satu-satunya masalah adalah bahwa saya menerima banyak kesalahan untuk alasan yang sama persis mereka membuat tag ng-src: Saya punya beberapa variabel di url dan browser berpikir gambar itu tidak ada.

Saya menyadari bahwa ada kemungkinan menulis kasar {{"style='background-image:url(myVariableUrl)'"}}, tetapi ini tampaknya 'kotor'.

Saya telah mencari banyak dan tidak dapat menemukan cara yang tepat untuk melakukan ini. Aplikasi saya menjadi berantakan karena semua kesalahan ini.

Jasper Schulte
sumber

Jawaban:

200

ngSrcadalah arahan asli, jadi sepertinya Anda menginginkan arahan serupa yang mengubah background-imagegaya div Anda .

Anda dapat menulis arahan Anda sendiri yang melakukan apa yang Anda inginkan. Sebagai contoh

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

Yang akan Anda panggil seperti ini

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

JSFiddle dengan kucing lucu sebagai bonus: http://jsfiddle.net/jaimem/aSjwk/1/

jaime
sumber
67
Arahan yang sangat bagus; satu-satunya masalah adalah tidak mendukung interpolasi. Saya mungkin akan memodifikasinya: jsfiddle.net/BinaryMuse/aSjwk/2
Michelle Tilley
1
Terima kasih, tidak masalah tanpa interpolasi, ia punya anak kucing!
Visgean Skeloru
Adakah masalah keamanan dengan ini jika Anda memuat dari sumber yang tidak dipercaya?
Aakil Fernandes
ini berfungsi, tetapi hanya jika url gambar Anda sudah ditentukan, gunakan @mythz jawab stackoverflow.com/a/15537359/1479680 untuk mendapatkan url yang lebih baik dan dapat digunakan
Magico
229

Yang ini bekerja untuk saya

<li ng-style="{'background-image':'url(/static/'+imgURL+')'}">...</li>
hooblei
sumber
22
Saya pikir ini harus menjadi jawaban yang diterima. Tidak perlu menambahkan arahan khusus.
Jakob Løkke Madsen
2
Saya menambahkan jawaban yang mirip dengan yang itu, hanya menggunakan interpolasi
wiherek
1
Itu kotor, dalam arti bahwa arahan cocok untuk semua, di mana pun Anda membutuhkan latar belakang yang dinamis. Pertanyaan menyebutkan itu terasa kurang dapat digunakan kembali.
Christian Bonato
Tidak berfungsi di Angular 1.5.8, ia masih mencoba memuat gambar dengan imgURLtidak disetel dan mencoba lagi ketika imgURLakan ditetapkan.
leroydev
Ini tidak benar, jika Anda memiliki variabel khusus seperti @% di URL Anda, itu akan rusak.
efwjames
69

Jawaban di atas tidak mendukung interpolasi yang dapat diamati (dan menghabiskan banyak waktu untuk mencoba debug). The jsFiddle Link di @BrandonTilley komentar adalah jawaban yang bekerja untuk saya, yang saya akan kembali posting di sini untuk pelestarian:

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

Contoh menggunakan controller dan template

Pengendali:

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

Templat:

Gunakan dalam template seperti ini:

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

atau seperti itu:

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

Dimungkinkan juga untuk melakukan hal seperti ini dengan ng-style:

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

yang tidak akan mencoba mengambil gambar yang tidak ada.

prinsip holografik
sumber
2
@sqren juga melihat ini jika Anda menggunakan versi Angular yang lebih baru (1.1.5 dan lebih tinggi): stackoverflow.com/a/12151492/1218080 . Dukungan untuk operator ternary aktual dalam pandangan telah ditambahkan.
asas holografik
rangkaian string sederhana seperti ini bekerja untuk saya pada objek lingkup, bukan interpolasi.
Shardul
25

Mirip dengan jawaban hooblei, hanya dengan interpolasi:

<li ng-style="{'background-image': 'url({{ image.source }})'}">...</li>
wiherek
sumber
1
Itu tidak bekerja di sini: <span ng-style="{'background-image': 'url(/styles/images/profile.png)'}" style="background-image: url("");"></span>. Pendekatan @hoblei berhasil.
Marcos Lima
Mendapatkan hasil yang sama :(
Kushal Jayswal
9

hanya masalah selera tetapi jika Anda lebih suka mengakses variabel atau fungsi secara langsung seperti ini:

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

alih-alih interpolasi seperti ini:

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

maka Anda dapat menentukan sedikit direktif berbeda dengan scope.$watchyang akan melakukan $parsepada atribut

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

ada lebih banyak latar belakang tentang ini di sini: AngularJS: Perbedaan antara metode $ mengamati dan $ menonton

kristok
sumber
2

@waktu jawaban Anda baik-baik saja. Tetapi jika halaman Anda memiliki $ http.get maka Anda telah menggunakan ng-if

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

di pabrik

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

di area pengontrol

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

dan tampilan jika Anda menggunakan ng-jika seperti di bawah ini maka Anda akan mendapatkan gambar dengan interpolasi sebaliknya, Anda tidak bisa mendapatkan gambar karena direktif mendapatkan nilai sebelum permintaan HTTP.

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

Saya telah menemukan dengan 1,5 komponen yang mengabstraksi styling dari DOM agar bekerja dengan baik dalam situasi async saya.

Contoh:

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

Dan di controller, ada yang suka ini:

this.$onChanges = onChanges;

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

function setBackgroundUrl(value){
    return 'url(' + value.imgUrl + ')';
}
Pat Migliaccio
sumber
0

Karena Anda sebutkan ng-srcdan sepertinya Anda ingin halaman selesai render sebelum memuat gambar Anda, Anda dapat mengubah jawaban jaime untuk menjalankan arahan asli setelah browser selesai render.

Posting blog ini menjelaskan hal ini dengan cukup baik; pada dasarnya, Anda memasukkan $timeoutpembungkus untuk window.setTimeoutsebelum fungsi panggilan balik di mana Anda membuat modifikasi ke CSS.

aralar
sumber