Angular 1.4.1 UI Router 10 $digest() iterasi ketika $state.go memanggil $stateChangeStart

Saya memiliki negara bagian yang memerlukan otorisasi. Saya mendengarkan acara $stateChangeStart dan jika toState.data.protecteddan pengguna tidak berwenang, saya memanggil e.preventDefault() dan $state.go('login').

Ketika saya membuka aplikasi di url root, saya secara otomatis dialihkan ke status terlindungi. Hal ini menyebabkan 10 $digest loop dan saya berakhir dalam status login ketika saya membuka aplikasi di url root dan saya secara otomatis dialihkan ke status terlindungi.

Uncaught Error: [$rootScope:infdig] 10 $digest() iterations reached. Aborting!

Lihat plnkr ini: http://plnkr.co/edit/1voh7m?p=preview

Saya berhasil menggunakan kode serupa di proyek berbeda dengan sudut 1.2.26 tanpa kesalahan.

Contoh kode angular 1.4.1, ui.router 0.2.15:

//config block
$urlRouterProvider.otherwise('/main');   
$stateProvider
 .state('main', {
   url: '/main',
     templateUrl: 'main.html',
     controller: 'MainController as main',
     data: {'protected': true}
 }) 
 .state('login', {
     url: '/login',
     templateUrl: 'login.html',
     controller: 'LoginController as login'
 });

// in a run block
$rootScope.$on("$stateChangeStart", function (event, toState) {
    if (!event.defaultPrevented && toState.data &&
            toState.data.protected) {
        // the user is not authorized, do not switch to state
        event.preventDefault();
        // go to login page
        $state.go('login');
    }
});

Tahukah Anda apa penyebab loop tersebut?

Saya ingin tahu apakah hal-hal tersebut mungkin terjadi seperti ini:

  1. Cegat transisi ke status main.submain
  2. Mulai transisi ke status login
  3. Router UI mendapat informasi bahwa transisi pertama dibatalkan
  4. Router UI menjalankan $urlRouter.update() dan memulai transisi ke main.submain

EDIT: Konfigurasi status yang disederhanakan.


person kvetis    schedule 02.07.2015    source sumber
comment
Di mana Anda mendefinisikan data apa yang dilindungi?   -  person user3727843    schedule 02.07.2015
comment
Menggunakan definisi negara bagian: data: {'protected': true} pada negara bagian utama. Negara bagian tersebut secara prototipikal diwariskan sehingga negara bagian utama.subutama memiliki nilai yang sama.   -  person kvetis    schedule 03.07.2015
comment
Saya minta maaf karena saya memasang plunk yang salah dan tidak menunjukkan masalah tersebut.   -  person kvetis    schedule 03.07.2015
comment
jika saya tidak salah, Anda sebaiknya tidak menggunakan $urlRouterProvider dengan satu cabang $urlRouterProvider.otherwise('/main'); , karena untuk url lain coba dialihkan ke 'main' dan Anda dalam loop tak terbatas, saya punya sedikit ubah plunker Anda coba periksa: plnkr.co/edit/RyWEusonoBhfQjwD32uu?p=preview   -  person Grundy    schedule 07.07.2015
comment
@Grundy Terima kasih. Saya baru saja datang ke sini untuk memposting jawaban untuk solusi serupa. Saya yakin Anda harus dapat menggunakan $urlRouterProvider.otherwise('/main'); dengan solusi saya - karena Anda hanya ingin memiliki pengalihan default. Saya suka saran Anda dan saya akan mengirimkan jawabannya sebentar lagi.   -  person kvetis    schedule 07.07.2015


Jawaban (1)


Ini adalah masalah UI.Router – lihat masalah ini di Github: https://github.com/angular-ui/ui-router/issues/600

Pada dasarnya jika Anda menggunakan .otherwise('/main') (juga ditunjukkan oleh @Grundy) maka urlnya diubah menjadi /main ketika jalurnya tidak dapat diselesaikan. Setelah $locationChangeSuccess pendengar saya dipanggil dan saya menolak pengalihan menggunakan event.preventDefault(). Hal ini menyebabkan lokasi berubah kembali ke jalur yang tidak diketahui sehingga menyebabkan jalur fallback digunakan kembali. Hal ini menyebabkan loop tak terbatas. Solusinya adalah ini:

$urlRouterProvider.otherwise(function($injector) {
  var $state = $injector.get('$state');
  $state.go('main');
});

Anda dapat menyatakan fungsi yang dipanggil dengan $injector dan Anda dapat mengalihkan ke status utama Anda (atau 404) tanpa perubahan lokasi bolak-balik. Terima kasih kepada teman-teman di Github, saya seharusnya mencari di sana sebelum memposting pertanyaan ini.

Plunk yang berfungsi: http://plnkr.co/edit/eQXaIk

person kvetis    schedule 07.07.2015
comment
Membantu, Terima kasih banyak! - person Rantiev; 06.06.2017