angular ng-if atau ng-show merespons dengan lambat (penundaan 2 detik?)

87

Saya mencoba untuk menampilkan atau menyembunyikan indikator pemuatan pada tombol ketika permintaan sedang sibuk. Saya melakukan itu dengan sudut dengan mengubah variabel $ scope.loading ketika permintaan sedang dimuat atau ketika selesai memuat.

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

        })
        .error(function(error){

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

Di bagian depan:

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

Ini berfungsi dengan baik, tetapi ikon pemuatan (ion-refreshing) ditampilkan selama sekitar 2 detik, sedangkan variabel $ scope diperbarui segera. Saya mencoba $ scope. $ Apply tetapi sepertinya bukan itu yang salah di sini, scope diperbarui dengan baik dan segera setelah permintaan. Hanya ikonnya yang tidak merespons dengan cukup cepat.

Terima kasih telah membantu saya memahami ini!

Jorre
sumber
2
Adakah animasi yang terlibat?
tasseKATT
Negatif. Tidak ada animasi yang terlibat. Menggunakan ng-class tampaknya membantu.
Jorre
Saya mengalami masalah yang sama atau serupa. Cakupan diperbarui segera dan benar - Saya memverifikasi ini dengan mencatat pesan dari dalam $scopefungsi yang ng-ifdigunakan untuk mengetahui apakah elemen yang relevan harus ditampilkan. Namun, tombol dengan ng-iftetap salah terlihat, atau tersembunyi, untuk beberapa detik. Kemudian setelah beberapa saat semua tombol mengambil status terlihat / tersembunyi yang diinginkan. - Saya mengatasi ini dengan menggunakan ng-hidesebagai gantinya. Versi sudut 1.2.16.
KajMagnus
Ada solusi untuk mereka yang tidak menggunakan animasi apa pun?
Zia Ul Rehman Mughal

Jawaban:

124

Coba hapus ngAnimate jika Anda tidak menggunakannya dari konfigurasi aplikasi dan halaman index.html:

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

@Sukasuka jika Anda masih memerlukan penggunaan ngAnimate, biarkan konfigurasi aplikasi Anda tidak tersentuh dan cukup tambahkan CSS berikut:

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

Itu akan menyembunyikan ikon animasi langsung setelah kondisi Anda terpenuhi.

Seperti yang Anda lihat, kami menyetel .ng-hide-animate menjadi tersembunyi. Inilah yang menyebabkan penundaan karena menunggu animasi selesai. Anda dapat menambahkan animasi ke acara hide seperti yang tersirat dari nama kelasnya daripada menyembunyikannya seperti pada contoh di atas.

Palvinder
sumber
1
Saya memiliki halaman sederhana dengan hanya beberapa ng-if, ng-showyang tampak lambat. Saya menghapus ngAnimatedan itu memperbaiki masalah untuk saya. Terima kasih!
Eamonn Gahan
1
Ini menyelesaikan masalah yang saya alami juga ... Tahukah Anda mengapa kehadiran ngAnimate menyebabkan transisi yang lambat?
Clark
Punya masalah yang sama - menghapus ngAnimate menyelesaikannya .. tetapi ini tidak baik .. banyak modul perlu ngAnimate untuk melakukan animasi keren .. apa yang harus dilakukan? ngAnimattias dimana kamu? :)
Spock
21
Dalam kasus ng-if, menambahkan hanya .ng-leave { display:none; }ke elemen melakukan trik untuk saya ( !importanttidak diperlukan).
Joao
40

Saya memiliki masalah yang sama, dan mengatasinya dengan menggunakan ng-class dengan nama kelas 'tersembunyi' untuk menyembunyikan elemen daripada menggunakan ng-if atau ng-show / ng-hide.

neimad
sumber
1
Sepertinya terkait dengan animasi dan / atau penangan acara. Tidak begitu yakin mengapa yang lain lambat, tapi saya ingin tahu
Thiago Festa
1
bagaimana kamu bisa melakukan ini?
jsmedmar
Ini jauh lebih cepat! Kenapa ini??
Aron
1
Saya akan berpikir ini hanya karena fakta bahwa menggunakan ngAnimate menerapkan perilaku animasi masuk / keluar ke elemen menggunakan ng-if / ng-show, sementara itu tidak melakukannya untuk perubahan dalam ekspresi kelas-ng.
John Rix
@neimad bagaimana ini dilakukan? Dalam kasus saya, saya perlu menggunakan ng-if untuk menguji apakah nilai properti adalah null(yang selama beberapa detik menunggu panggilan api), jadi dua elemen terpilih ditampilkan secara singkat. Jadi, apakah Anda tidak menggunakan ng-if sama sekali? Terima kasih.
Chris22
15

Saya menemukan beberapa solusi di sini , tetapi yang terbaik bagi saya adalah mengganti gaya untuk kelas .ng-animate:

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

Dalam 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>

Ini adalah contohnya: http://jsfiddle.net/9krLr/27/

Saya harap membantu Anda.

Ruben Perez
sumber
10

Saya menghadapi masalah serupa, saya dulu $scope.$evalAsync() memaksa memperbarui pengikatan.

Ini bekerja seperti pesona.

Hindari penggunaan $scope.$applykarena dapat bertentangan dengan fase $ digest yang sudah berjalan.

if(selectedStatistics.length === 0 || selectedWorkgroups.length === 0){
    ctrl.isSaveDisabled = true;
    $scope.$evalAsync();
} else{
    ctrl.isSaveDisabled = false;
    $scope.$evalAsync();
}
rach8garg.dll
sumber
Bekerja untuk saya. Tetapi apakah itu memiliki kekurangan?
Sarah Tammam
1
Saya belum menemukan satupun. Ini sangat berguna dalam kasus operasi asinkron.
rach8garg
1
Terima kasih atas balasannya yang membantu :)
Sarah Tammam
Ngomong-ngomong, masalah penundaan ini terutama terjadi di lingkungan localhost dan jarang dalam produksi - tidak tahu mengapa
Abdeali Chandanwala
1

Saya memiliki masalah yang sama saat menggunakan

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

Dalam kasus saya, saya menyelesaikannya dengan menambahkan kelas:

.hidden {
  display: none;
}

lalu menambahkan kelas secara bersyarat daripada menggunakan *ngIf:

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

Jika selalu menggunakannya dengan cara ini, saya akan mempertimbangkan shouldShowuntuk mengganti nama menjadi shouldHide(dan meniadakan logika yang menetapkannya), sehingga dapat digunakan sebagai shouldHidepengganti!shouldShow .

Jika Anda memiliki display: flexCSS untuk kelas DIV yang ada, properti tampilan itu mungkin lebih diutamakan daripada display: hidden. Cara yang mudah dapat digunakan display: none !importantsebagai gantinya, tetapi sering kali ada solusi yang lebih baik untuk memastikan prioritas dengan cara lain. Berikut adalah bacaan yang bagus tentang alternatif .

Kent Munthe Caspersen
sumber
0

dalam versi sudut 1.5.x menambahkan $scope.$apply()setelah perubahan kondisi selesai pekerjaan untuk saya di sini adalah contoh fungsi

$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();
            }


        }
mohamed
sumber