angularjs:background-image:url(…)と同等のng-src


150

angularjsでは、持っているタグNG-SRC angularjsが間に配置された変数を評価するために取得する前に、無効なURLのためにエラーが表示されないことを目的あり{{とを}}

問題はbackground-image、URLへのセットでかなりのDIVを使用することです。これbackground-sizeは、DIVの正確なサイズに画像をトリミングする優れたCSS3プロパティがあるためです。

唯一の問題は、ng-srcタグを作成したのとまったく同じ理由で多くのエラーを受け取ることです。URLにいくつかの変数があり、ブラウザーは画像が存在しないと見なしています。

私は原油を書く可能性があることを理解していますが、{{"style='background-image:url(myVariableUrl)'"}}これは「汚い」ようです。

私はたくさん検索しましたが、これを行う正しい方法を見つけることができません。これらのエラーのすべてが原因で、アプリがごちゃごちゃになっています。

回答:


200

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/


67
とても素敵なディレクティブ。唯一の問題は、補間をサポートしていないことです。私はおそらくそれをこのように変更するでしょう:jsfiddle.net/BinaryMuse/aSjwk/2
ミシェル・ティリー

1
ありがとう、補間がなくても問題ありません。子猫がいます!
Visgean Skeloru 2013

信頼できないソースからロードしている場合、これに関するセキュリティの問題はありますか?
アーキルフェルナンデス2015

これは機能しますが、画像のURLが既に定義されている場合にのみ、@ mythzの回答stackoverflow.com/a/15537359/1479680を使用して、より見やすいURLを作成します
Magico

229

これは私のために働く

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

22
これは受け入れられる答えだと思います。カスタムディレクティブを追加する必要はありません。
JakobLøkkeMadsen 2014

2
私は補間を使用して、それと同様の答えを追加しました
wiherek

1
ディレクティブは、動的な背景が必要なすべての場所に当てはまるという意味で、より汚いものです。質問は、再利用可能性が低く感じられたと述べました。
Christian Bonato 16年

Angular 1.5.8では機能しませんが、imgURL未設定で画像を読み込もうとし、imgURL取得時に再試行します。
leroydev 2016

これは誤りです。URLに@%のような特別な変数があると、壊れます。
efwjames 2016

69

上記の答えは、観察可能な補間をサポートしていません(デバッグに多くの時間を費やしています)。@BrandonTilleyコメントのjsFiddleリンクは私にとって有効な答えでした。保存するためにここに再投稿します。

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は、Angularの新しいバージョン(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アプローチが機能しました。
マルコスリマ

同じ結果を得る:(
Kushal Jayswal 2017年

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:$ observeメソッドと$ watchメソッドの違い


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

非同期の状況で最適に機能するように、DOMからスタイルを抽象化する1.5コンポーネントが見つかりました。

例:

<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し、画像をロードする前にページのレンダリングを終了したいように見えるので、ブラウザがレンダリングを完了し後にネイティブディレクティブを実行するようにjaimeの回答を変更できます。

このブログ投稿では、これについてかなりよく説明しています。基本的に、あなたは挿入$timeoutラッパーのためにwindow.setTimeoutあなたがCSSにこれらの変更を加える前記コールバック関数の前に。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.