Angularjs: ng-src эквивалент для background-image: url (...)

В angularjs у вас есть тег ng-src, целью которого является то, что вы не получите ошибку для недопустимого URL-адреса до того, как angularjs получит для оценки переменных, помещенных между {{ и }}.

Проблема в том, что я использую довольно DIV с background-image, установленным в URL. Я делаю это из-за превосходного свойства CSS3 background-size, который обрезает изображение с точным размером DIV.

Единственная проблема заключается в том, что я получаю много ошибок по той же причине, что и тег ng-src: у меня есть некоторые переменные в URL-адресе, и браузер думает, что изображение не существует.

Я понимаю, что есть возможность написать грубую {{"style='background-image:url(myVariableUrl)'"}}, но это кажется "грязным".

Я много искал и не могу найти правильный способ сделать это. Из-за всех этих ошибок мое приложение становится бесполезным.

Ответ 1

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/

Ответ 2

Это работает для меня

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

Ответ 3

Вышеприведенный ответ не поддерживает наблюдаемую интерполяцию (и мне пришлось потратить много времени на отладку). Ссылка 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 
*/

$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

Также можно сделать что-то подобное с помощью ng-style:

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

который не попытался бы получить несуществующее изображение.

Ответ 5

Похож на hooblei ответ, просто с интерполяцией:

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

Ответ 6

просто вопрос вкуса, но если вы предпочитаете доступ к переменной или функции прямо следующим образом:

<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

Ответ 7

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

в factory

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

Ответ 8

Я нашел с 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 + ')';
}

Ответ 9

Поскольку вы упомянули ng-src и кажется, что вы хотите, чтобы страница заканчивала рендеринг перед загрузкой изображения, вы можете изменить ответ jaime для запуска директивы native после завершения рендеринга браузера.

Это сообщение в блоге объясняет это довольно хорошо; по существу, вы вставляете $timeout обертку для window.setTimeout перед функцией обратного вызова, в которой вы вносите эти изменения в CSS.