Angular ng-if или ng-show реагирует медленно (2-секундная задержка?)

Я пытаюсь показать или скрыть индикатор загрузки на кнопке, когда запрос занят. Я делаю это с помощью angular, изменяя переменную $scope.loading при загрузке запроса или при загрузке.

 $scope.login = function(){
     $scope.loading = true;
    apiFactory.getToken()
        .success(function(data){

        })
        .error(function(error){

        })
         .finally(function(){
               $timeout(function() {
                 $scope.loading = false;
               }, 0);
         });
 };

В интерфейсе:

<button ng-disabled="loading" class="button button-outline button-positive" type="submit">
Log in 
<span ng-if="loading" class="ion-refreshing"></span>
</button>

Это отлично работает, но значок загрузки (ионное обновление) отображается примерно на 2 секунды, а переменная $scope обновляется немедленно. Я пробовал $scope. $Apply, но это не похоже на то, что здесь неправильно, область обновления обновляется просто отлично и сразу после запроса. Это просто значок, который не отвечает достаточно быстро.

Спасибо, что помогли мне понять это!

Ответ 1

Попробуйте удалить ngAnimate, если вы не используете его со своей конфигурации приложения и страницы index.html:

angular.module('myApp', [...'ngAnimate',...])

@Spock; если вы все еще нуждаетесь в использовании ngAnimate, оставьте конфигурацию приложения нетронутой и просто добавьте следующий CSS:

.ng-hide.ng-hide-animate{
     display: none !important;
}

Это скроет анимированный значок сразу после выполнения вашего условия.

Как вы видите, мы устанавливаем .ng-hide-animate для скрытия. Это то, что вызывает задержку, когда она ждет завершения анимации. Вы можете добавить анимацию к вашему событию скрыть, как следует из имени класса, вместо того, чтобы скрывать ее, как в примере выше.

Ответ 2

У меня была такая же проблема, и я работал над ней, используя ng-класс со "скрытым" именем класса, чтобы скрыть элемент вместо использования ng-if или ng-show/ng-hide.

Ответ 3

Я нашел несколько решений здесь, но лучшим для меня было переопределение стиля для класса .ng-animate:

.ng-animate.no-animate {
    transition: 0s none;
    -webkit-transition: 0s none;
    animation: 0s none;
    -webkit-animation: 0s none;
}

В html:

<button ng-disabled="loading" class="button button-outline button-positive" type="submit">
    Log in 
    <span ng-if="loading" class="ion-refreshing no-animate"></span>
</button>

Это пример: http://jsfiddle.net/9krLr/27/

Я надеюсь помочь вам.

Ответ 4

Я столкнулся с аналогичной проблемой, я использовал $scope.$evalAsync(), чтобы принудительно обновить привязку.

Он работает как шарм.

Избегайте использования $scope.$apply, поскольку оно может конфликтовать с уже запущенной фазой $digest.

if(selectedStatistics.length === 0 || selectedWorkgroups.length === 0){
    ctrl.isSaveDisabled = true;
    $scope.$evalAsync();
} else{
    ctrl.isSaveDisabled = false;
    $scope.$evalAsync();
}

Ответ 5

в angular версии 1.5.x добавив $scope.$apply() после изменения условия выполнения задания для меня, вот примерная функция

$scope.addSample = function(PDF)
        {
            var validTypes ="application/pdf";
            if(PDF.type == validTypes)
            {
                //checking if the type is Pdf and only pdf
                $scope.samplePDF= PDF.files[0];
                $scope.validError = false;
                $scope.$apply();
            }

            else
            {
                 $scope.validError = true;
                 $scope.samplePDF= null;
                 $scope.$apply();
            }


        }