Подтвердить что ты не робот

AngularJS - ng-style не обновляет свойство css background

У меня есть служба, которая возвращает URL-адрес изображения, и вызывается с помощью следующего кода:

angular.forEach(results, function (item) {
     item.img = "/images/searchItem.jpg";
     $http.post("https://my.api.com/?id=" + item.id).success(
           function (url) {
               item.img = url;
           });
});

В моем представлении у меня было изображение с атрибутом ng-src, которое получилось так:

<img  ng-src="{{item.img}}">

Затем я решил вместо этого использовать фоновое изображение на SPAN:

<span ng-style="{'background':'transparent url({{item.img}})'}"></span>

теперь поток работает только при первом запуске, после чего я вижу (в консоли) следующий html

<span ng-style="{'background':'transparent url(http://expertsimages.liveperson.com/images/rating/rate10.gif)'}" style="background-image: url(https://fb.lp-chat.com/images/searchItem.jpg); background-color: transparent; background-position: initial initial; background-repeat: initial initial;"></span>

который указывает, что переменная обновлена, однако html все еще находится в исходном состоянии.

Я попытался вызвать apply/digest на пост-успех, но получил ошибку $digest уже в процессе (что имеет смысл). Дело в том, что после обычного дайджеста (например, при других изменениях ui) применяется стиль, и я вижу правильное изображение.

Что мне здесь не хватает?

Update: Я создал скрипт JS, который демонстрирует эту проблему... выглядит как ошибка в angular для меня.

4b9b3361

Ответ 1

Я тоже столкнулся с этим. Вместо оценки с помощью {{ }} используйте конкатенацию string + value.

Это будет работать:

<span ng-style="{'background':'transparent url(' + item.img + ')'}"></span>)

Здесь рабочая версия вашего скрипта

Ответ 2

Это не работает, потому что angular оценивает содержимое единственной скобки только один раз и не находит переменную, которую вы хотите связать внутри этой строки.

Однако вы могли бы создать свою собственную директиву как таковую:

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

а затем используйте его в шаблоне следующим образом:

<div ng-if="vis" class="container" back-img="{{imgSrc}}"></div>

Я обновил свою скрипку и, похоже, отлично работает http://jsfiddle.net/dS4pB/3/

Ответ 3

Если вы в настоящее время обновляете переменную области видимости, оберните ее в вызове $timeout, чтобы нажимать обновления в свою область действия, а затем ваше представление, это позволит эффективно обновить обновление до следующего digest, избегая дайджеста уже в процессе:

    $timeout(function(){
        $scope.var = value;
    });

Этот вопрос может дать вам полезную информацию о apply vs timeout и т.д.

Ответ 4

вы, вероятно, сталкиваетесь с той же проблемой, с которой я столкнулся недавно, и решили с помощью ng-bind.

проверьте ответ, объясненный в этом вопросе:

AngularJS: Почему ng-bind лучше, чем {{}} в angular?

как только я использовал ng-bind, мой innerhtml был правильно обновлен.

Ответ 5

Angular 2 имеет приятный способ сделать это, [style. *] = "value"

<span [style.background-color]="transparent" [style.background-image]="item.img"></span>