Angular.js: ng-show / hide ditunda pada elemen yang beranimasi

Dibuat pada 16 Jul 2014  ·  17Komentar  ·  Sumber: angular/angular.js

Ini bukan perilaku yang diharapkan jika Anda melakukan animasi terus-menerus pada sesuatu seperti pemintal pemuatan dan hanya ingin menyembunyikan atau menampilkannya segera.

Elemen tidak diperintahkan untuk dikelola oleh ng-animate, saya hanya ingin ng-show / hide normal terjadi secara instan, dan animasi css apa pun yang sedang berlangsung seharusnya tidak relevan, menurut saya.

Biola: http://jsfiddle.net/PvS8k/2/

Hapus centang "show loader" dan perhatikan bahwa perlu beberapa detik untuk benar-benar menghilang.

Saya pikir ini adalah perubahan baru-baru ini karena pemuat kami tidak menempel di aplikasi kami sebelum meningkatkan. Saya pikir kami berada di 1,12 sebelumnya.

Saya pasti melewatkan sesuatu dalam pemahaman saya tentang cara menggunakan / tidak menggunakan ng-animate, bukan? Dalam hal ini saya sebenarnya ingin TIDAK menggunakannya, tetapi jika saya dapat menggunakannya untuk mengabaikan elemen ini, itu juga akan berhasil. Perilaku yang benar-benar mengejutkan.

ngAnimate broken expected use bug

Komentar yang paling membantu

@ tole42 Ini solusinya:

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

Semua 17 komentar

ngAnimate serakah karena mengasumsikan bahwa semua bingkai utama / kode transisi yang aktif pada elemen selama salah satu pemicu ada untuk dianimasikan melalui ngAnimate. Oleh karena itu, dalam kasus ini, meskipun .loader tidak ada hubungannya dengan ngShow / ngHide, itu masih diambil sebagai animasi yang valid.

Untuk menyiasatinya, cukup hapus gaya animasi ketika kelas .ng-animate diterapkan pada elemen.

http://jsfiddle.net/PvS8k/4/

Ini adalah masalah dengan pewarisan CSS. Jika ada cara yang lebih baik untuk mendeteksi gaya tanpa harus hanya mengandalkan getComputedStyle, maka kebiasaan semacam ini mungkin dapat dihindari.

@matsko Saya rasa kasus khusus ini sebenarnya adalah regresi. Seperti yang Anda lihat di plunker @SimpleAsCouldBe, atau di plunker ini http://plnkr.co/edit/5cfIXfNryNOzK66q9YWL?p=preview , di 1.2.17, elemen tidak langsung menghilang, tetapi di 1.2.16, tidak. Ini kemungkinan besar karena https://github.com/angular/angular.js/commit/55b2f0e8620465559016b424967d90a86af597c0
Saya pikir ini memerlukan pemeriksaan lebih dekat; setidaknya harus ada catatan di changelog dan dokumen tentang ini.

Terima kasih atas solusinya, ini melakukan trik seperti yang diharapkan.

Dua poin. Satu khusus untuk ng-show dan satu lagi umum.

ng-show + animasi tak terbatas:

Haruskah animasi tak terbatas _really_ menunda penyembunyian ng-show ? Saya mencoba menghitung detik dan tidak selalu 4 detik menunggu untuk menyembunyikannya. Kadang-kadang 5 atau 7 ... tampaknya bervariasi. Juga Jika Anda mengaktifkan dan menonaktifkan lagi kotak centang itu tidak akan pernah bersembunyi. Saya pikir ada bug yang sebenarnya bersembunyi di sini di suatu tempat.

Filisofis

Sebagai non-kontributor, saya tidak banyak bicara, tetapi mungkin memilih keluar bukanlah strategi yang tepat untuk perpustakaan ini. Ini sangat ajaib memiliki perpustakaan JS bereaksi terhadap aturan CSS .. Jika saya harus menandai elemen dengan ng-animatable saya akan jauh lebih siap untuk ini.

@SimpleAsCouldBe ya Saya telah memikirkan hal yang sama bahwa mungkin sebaiknya semua animasi memiliki prefiks animate- class sedemikian rupa sehingga ngAnimate kemudian akan terhubung ke animasi.

Mengenai penundaan, bukan karena ada penundaan, tetapi ngAnimate membatalkan bagian tak terbatas dan hanya menjalankan animasi satu kali. Oleh karena itu, ketika Anda menyembunyikannya, itu menunggu selama 2s * 1,5 = 3 detik dan kemudian menjalankan pemeriksaan batas waktu dan menutup animasi. Jadi ini adalah jendela waktu yang tidak perlu yang seharusnya tidak ada di sana - hanya deteksi gaya CSS yang sangat terbatas.

@Narretz sementara komit yang Anda berikan dapat mempengaruhi contoh khusus ini, sebenarnya tidak ada hubungannya dengan regresi. Alasannya adalah karena gaya .ng-hide yang sudah ada sebelum perbaikan menerapkan nilai display:none pada waktu yang berbeda. Tetapi perbaikan saat ini HANYA menerapkannya setelah semua animasi selesai (setelah kelas .ng-animate dihapus).

Simak demonya di bawah ini. Lihat bagaimana ada dua set penyeleksi untuk kelas .blue : satu dengan .ng-animate dan tanpa itu. Meskipun kelas .blue diterapkan segera, ngAnimate masih menganggap animasi sudah jatuh tempo dan akan menunggu 3s (ingat 2s * 1.5) sebelum menerapkan batas waktu penutupan. Biasanya akan menjadi 2s, tetapi event animationend tidak pernah dijalankan karena animasi sebenarnya pada elemen (yang ada karena .loader ) tidak terbatas dan tidak dipicu oleh ng-class ( atau ng-show untuk contoh sebelumnya). Sehingga dikatakan ini tidak berlaku karena perbaikan bug sebelumnya.
http://jsfiddle.net/PvS8k/15/

Mungkin yang terbaik adalah membuat ngAnimate kurang naif dan hanya beranimasi ketika animated- ada sebagai awalan CSS di suatu tempat.

Saya pikir jika Anda terbuka untuk perubahan besar seperti penanganan animasi keikutsertaan, itu akan menciptakan pengalaman pengembang yang kurang mengejutkan.

Apakah Anda terbuka untuk memberi awalan dengan sesuatu yang spesifik bersudut seperti .ng-animate daripada .animate biasa-biasa saja?

Saya memiliki masalah yang sama:
Dengan sudut> = 1.2.17 http://jsfiddle.net/9krLr/17/
Dengan sudut 1.2.16 semuanya baik-baik saja: http://jsfiddle.net/EZpQQ/1/

@ tole42 Ini solusinya:

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

Terima kasih atas bantuan Anda. Solusi tidak berhasil :(
Apa yang salah?
http://jsfiddle.net/9krLr/21/

@ tole42 Tidak ada dalam biola itu yang hidup, sejauh yang saya bisa lihat. Apakah bagian animasi dari perpustakaan Foundation? Kasus pembuatan ulang yang lebih langsung akan membuatnya lebih mudah untuk di-debug. Tidak terlihat seperti masalah yang sama bagi saya.

Saya yakin saya melihat masalah yang sama dengan @ tole42 . Dengan ngAnimate termasuk dalam sebuah modul, fungsionalitas ng-hide / ng-show standar tidak bekerja dengan benar untuk kasus dasar saat Anda _not_ mencoba untuk menganimasikannya. Dengan kata lain, saat Anda menggunakan ng-hide / ng-show pada elemen biasa tanpa kelas animasi yang diterapkan.

<div ng-hide="hideme">hide me</div>

Jika saya menginginkan animasi di kulit itu, saya akan melakukan sesuatu seperti:

<div ng-hide="hideme" class="myanimation">hide me</div>

Ada beberapa contoh dalam aplikasi di mana Anda mungkin ingin menganimasikan pertunjukan / sembunyikan dan contoh lain di mana Anda tidak ingin menganimasikan. Dalam kasus di mana Anda tidak ingin beranimasi, Anda tidak menghias elemen yang ditampilkan / disembunyikan dengan kelas animasi khusus apa pun. Dalam contoh ini, Angular hanya menambahkan kelas "ng-hide" ke elemen tersembunyi.

Jika Anda sama sekali tidak menyertakan ngAnimate dalam modul Anda, ini berfungsi seperti yang diharapkan: elemen segera menghilang. Namun hanya dengan memasukkan ngAnimate, Anda mendapatkan perilaku yang ditampilkan dalam dua fiddle yang diposting

Beberapa solusi yang tampaknya berhasil adalah:

.ng-hide-add {
    transition: 0s linear all;
}

Atau:

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

Tetapi tampaknya tidak benar bahwa itu harus diperlukan dalam kasus di mana Anda hanya mencoba menyembunyikan sesuatu dengan cara non-animasi.

Hanya untuk menindaklanjuti beberapa penemuan tambahan ...

Mencoba meringkas masalah ke skenario yang paling sederhana - menampilkan / menyembunyikan div biasa - masalah tidak terwujud.

Saya perhatikan di biola yang diposting oleh @ tole42 bahwa foundation.css sedang digunakan, dan contohnya menunjukkan masalah dengan menampilkan / menyembunyikan kolom input. Pengalaman saya serupa (melihat manifes masalah dengan kolom input), tetapi menggunakan bootstrap.css. Menggali kedua file css tersebut lebih dekat, keduanya menerapkan transisi css ke kolom input.

Transisi css tersebut tampaknya menjadi penyebab sebenarnya, karena angular-animate mengambil durasinya. Itulah yang menyebabkan penundaan visual saat menampilkan / menyembunyikan elemen tersebut, meskipun Anda tidak secara sengaja mencoba untuk menghidupkan transisi tersebut.

Jadi menurut saya ini bukan masalah yang harus diselesaikan Angular. Ini lebih merupakan efek samping dari penggunaan angular-animate dengan pustaka css lainnya, yang mungkin memiliki beberapa transisi css yang tidak Anda harapkan!

Butuh waktu lama untuk melacak akar masalahnya, tetapi ada baiknya akhirnya menemukan alasan yang masuk akal.

Ya, ini adalah masalah penting dengan ngAnimate, tetapi karena kurangnya kontrol getComputedStyle dan aliran transisi di pustaka lain, ngAnimate tidak dapat mendeteksi ini.

Ada dua solusi untuk memperbaikinya:

1) Ganti gaya untuk kelas .ng-animate :
http://jsfiddle.net/9krLr/27/

Alasan mengapa ini tidak berhasil untuk Anda sebelumnya adalah karena kurangnya kekhususan CSS.

2) Gunakan $animateProvider.classNameFilter(regex) . Regex dalam hal ini akan menempatkan hard block pada semua animasi yang dipicu ngAnimate dan hanya memungkinkan animasi berlangsung jika regex cocok dengan className yang ada pada elemen yang ingin Anda animasikan.

Oh, meletakkan konfigurasi di penyedia adalah cara yang bagus, saya sangat menyukainya, @matsko!

@pnutshellmenace terima kasih atas solusi cepatnya. Ini menyelamatkan hari saya.

Saya tidak mengerti apa solusi terakhir di sini. @matsko menyatakan:

Mungkin yang terbaik adalah membuat ngAnimate kurang naif dan hanya beranimasi saat dianimasikan- apakah ada awalan CSS di suatu tempat

Tapi saya tidak melihat implementasi seperti itu. Saya melihat $animateProvider.classNameFilter(regex) tetapi sekali lagi, saya memiliki lebih banyak pertanyaan daripada jawaban. Apa cara praktis untuk mengimplementasikan ini dan bagaimana jika ada lebih dari satu nama kelas yang dapat diterapkan?

Saya tidak melihat alasan mengapa ngAnimate harus menganggap saya ingin menghidupkan semuanya. Akan selalu ada hal-hal yang tidak ingin saya animasikan, dan saat ini saya memiliki lebih banyak hal yang tidak ingin saya animasikan daripada sebaliknya, yang membuat penataan gaya manual untuk menonaktifkan transisi menjadi tidak menarik.

Sunting: Menemukan entri blog ini yang menempatkan segala sesuatunya ke dalam perspektif ... Saya akan mencobanya: http://blog.fgribreau.com/2014/03/how-to-configure-ng-animate-to- work-on.html

Sunting 2: Menambahkan $animateProvider.classNameFilter(/enable-animate/); berhasil, tetapi dalam prosesnya saya menemukan beberapa perilaku yang menarik:

Saya telah menyertakan file .js dari modul sudut pihak ketiga yang memiliki ketergantungan pada ngAnimate, dan entah bagaimana itu menyebabkan animasi dipicu bahkan pada modul saya sendiri. Entah bagaimana ngAnimate memengaruhi cakupan modul induk?

Saya lebih suka jawaban ini menggunakan $scope.$evalAsync(); untuk operasi asinkron. bekerja dengan baik.

Apakah halaman ini membantu?
0 / 5 - 0 peringkat