кутова ng-if або ng-show відповідає повільно (затримка 2 секунди?)


87

Я намагаюся показати або приховати індикатор завантаження на кнопці, коли запит зайнятий. Я роблю це з 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, але, схоже, це не те, що тут не так, область оновлюється чудово і відразу після запиту. Це просто значок, який реагує недостатньо швидко.

Дякую, що допомогли мені це зрозуміти!


2
Будь-яка анімація?
tasseKATT

Негативні. Жодної анімації не задіяно. Використання ng-class замість цього, здається, допомагає.
Jorre

У мене така сама або подібна проблема. Область застосування оновлюється негайно та коректно - я перевірив це, реєструючи повідомлення з використанням $scopeфункцій, які ng-ifвикористовуються для з'ясування відповідних елементів. Однак кнопки з ng-ifдеякою секундою залишаються неправильно видимими або прихованими. Потім через деякий час всі кнопки приймають передбачувані видимі / приховані стани. - Я обійшов це, використовуючи ng-hideзамість цього. Кутова версія 1.2.16.
KajMagnus

Будь-яке рішення для тих, хто не використовує жодної анімації?
Zia Ul Rehman Mughal

Відповіді:


124

Спробуйте видалити ngAnimate, якщо ви не використовуєте його зі сторінки конфігурації програми та сторінки index.html:

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

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

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

Це приховає анімований значок відразу після того, як ваша умова буде виконана.

Як бачите, ми встановлюємо .ng-hide-animate на hidden. Саме це спричиняє затримку, оскільки вона чекає завершення анімації. Ви можете додати анімацію до своєї події приховування, як випливає з назви класу, замість того, щоб приховувати її, як у прикладі вище.


1
У мене була проста сторінка з лише кількома ng-if, ng-showщо було помітно повільно. Я видалив, ngAnimateі це вирішило проблему для мене. Дякую!
Eamonn Gahan

1
Це вирішило проблему, з якою я теж мав справу ... Чи знаєте ви, чому наявність ngAnimate спричиняла повільний перехід?
Clark

Була та сама проблема - видалення ngAnimate це вирішило .. але це погано .. багатьом модулям потрібен ngAnimate, щоб робити круті анімації .. що робити? ngAnimattias де ти? :)
Спок,

21
У випадку ng-if, додавання просто .ng-leave { display:none; }до елемента зробило для мене фокус ( !importantне потрібно).
Жоао

40

У мене була та ж проблема, і я обійшов її, використовуючи ng-class з назвою класу `` прихований '', щоб приховати елемент, замість використання ng-if або ng-show / ng-hide.


1
Здається, пов’язане з анімацією та / або обробниками подій. Не зовсім впевнений, чому інші повільні, але я хотів би знати
Тіаго Феста

1
як ти можеш це зробити?
jsmedmar

Це набагато швидше! Чому це??
Арон

1
Я думаю, це просто зводиться до того, що використання ngAnimate застосовує поведінку анімації входу / виходу до елементів, що використовують ng-if / ng-show, тоді як це не робить для змін у виразах класу ng.
Джон Рікс,

@neimad як це робиться? У моєму випадку мені потрібно використовувати ng-if, щоб перевірити, чи є значення властивості null(яке воно становить пару секунд, очікуючи виклику api), тому два елементи вибору коротко відображаються. То ви взагалі не використовуєте ng-if ? Дякую.
Chris22

15

Я знайшов тут кілька рішень , але найкращим для мене було перевизначення стилю для класу .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/

Я сподіваюся вам допомогти.


10

Я стикався з подібною проблемою, я використовував $scope.$evalAsync() змушував оновлювати прив’язку.

Це працює як шарм.

Уникайте використання, $scope.$applyоскільки це може суперечити вже запущеній фазі $ дайджесту.

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

Працював у мене. Але чи є у цього якісь недоліки?
Сара Таммам,

1
Я не зустрічав жодного. Це дуже зручно у випадку асинхронних операцій.
rach8garg

1
Дякую за корисну відповідь :)
Сара Таммам

Ця відповідь, здається, джек-пот, дякую.
Абдеалі Чанданвала

До речі, це відкладене питання в основному відбувається в середовищі localhost і рідко у виробництві - не знаю чому
Abdeali Chandanwala

1

У мене була та сама проблема при використанні

<div *ngIf='shouldShow'>
    <!-- Rest of DIV content here -->
</div>

У моєму випадку я вирішив це, додавши клас:

.hidden {
  display: none;
}

а потім умовно додати клас замість використання *ngIf:

<div [ngClass]="{'hidden': !shouldShow}">
    <!-- Rest of DIV content here -->
</div>

Якщо завжди використовувати його таким чином, я хотів би перейменувати shouldShowна shouldHide(і заперечити логіку, яка його призначає), тому його можна використовувати якshouldHide замість !shouldShow.

Якщо display: flexу вашому CSS є існуючий клас DIV, властивість display може мати перевагу над display: hidden. display: none !importantНатомість можна використати просте виправлення , але часто є кращі рішення для забезпечення переваги іншими способами. Ось гарне читання про альтернативи .


0

в кутовій версії 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();
            }


        }
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.