Alihkan status ke substrat default dengan UI-Router di AngularJS

89

Saya membuat halaman berbasis tab yang menampilkan beberapa data. Saya menggunakan UI-Router di AngularJs untuk mendaftarkan status.

Tujuan saya adalah membuka satu tab default pada pemuatan halaman. Setiap tab memiliki sub tab, dan saya ingin sub tab default terbuka saat mengganti tab.

Saya sedang menguji dengan onEnterfungsi dan di dalam yang saya gunakan $state.go('mainstate.substate');tetapi tampaknya tidak berfungsi karena masalah efek loop (di state.go ke substate itu memanggil status induknya dan seterusnya, dan itu berubah menjadi loop).

$stateProvider

.state('main', {
  url: '/main',
  templateUrl: 'main.html',
  onEnter: function($state) {
    $state.go('main.street');
  }
})

.state('main.street', {
  url: '/street',
  templateUrl: 'submenu.html',
  params: {tabName: 'street'}
})

Di sini saya membuat demo plunker .

Untuk saat ini semuanya berfungsi, kecuali saya tidak memiliki tab default terbuka dan itulah yang saya butuhkan.

Terima kasih atas saran, pendapat, dan ide Anda.

Leo
sumber

Jawaban:

172

Pembaruan: 1.0 Maju Mendukung redirectTo di luar kotak.

https://ui-router.github.io/ng1/docs/latest/interfaces/state.statedeclaration.html#redirectto


Saya membuat contoh di sini .

Solusi ini berasal dari "Komentar" yang bagus untuk masalah pengalihan menggunakan .when() ( https://stackoverflow.com/a/27131114/1679310 ) dan solusi yang sangat keren untuk itu (oleh Chris T, tetapi pos aslinya adalah oleh yahyaKacem)

https://github.com/angular-ui/ui-router/issues/1584#issuecomment-75137373

Jadi pertama-tama mari kita kembangkan main dengan pengaturan redirection:

$stateProvider
    .state('main', {
      url: '/main',
      templateUrl: 'main.html',
      redirectTo: 'main.street',
    })

Dan tambahkan hanya beberapa baris ini untuk dijalankan

app.run(['$rootScope', '$state', function($rootScope, $state) {

    $rootScope.$on('$stateChangeStart', function(evt, to, params) {
      if (to.redirectTo) {
        evt.preventDefault();
        $state.go(to.redirectTo, params, {location: 'replace'})
      }
    });
}]);

Dengan cara ini kita dapat menyesuaikan status kita dengan pengalihan default ... Periksa di sini

EDIT: Menambahkan opsi dari komentar oleh @Alec untuk menjaga riwayat browser.

Radim Köhler
sumber
4
Ini sepertinya membentur tombol kembali.
Scott Sword
6
@ Swordfish0321 untuk memperbaiki tombol kembali, lakukan perubahan kecil ini: $state.go(to.redirectTo, params, {location: 'replace'});Ini akan menyebabkan status baru menggantikan status sebelumnya (yaitu saat kami dialihkan) dalam riwayat. Lihat dokumen untuk $ state.go: angular-ui.github.io/ui-router/site/#/api/…
Alec
2
Hanya ingin menambahkan bahwa ini sangat mirip dengan apa yang ingin saya lakukan, tetapi saya ingin URL default daripada menggantinya, ini mudah dilakukan dengan mengubah '$stateChangeStart'ke'$stateChangeSuccess'
Harga Matti
6
ui-router 1.0 telah membangun dukungan untuk ini: ui-router.github.io/guide/ng1/…
Gert-Jan
21

Bahkan jika solusi yang diusulkan oleh Radim ini benar-benar berfungsi , saya perlu mengingat setiap sub tab (status) tab.

Jadi saya menemukan solusi lain yang melakukan hal yang sama tetapi juga mengingat setiap substrat tab.

Yang harus saya lakukan adalah menginstal ui-router-extras dan menggunakan fitur pengalihan status dalam :

$stateProvider
  .state('main.street', {
     url: '/main/street',
     templateUrl: 'main.html',
     deepStateRedirect: { default: { state: 'main.street.cloud' } },
  });

Terima kasih!

Leo
sumber
12

Pada versi 1.0 dari ui-router, ini mendukung redirectToproperti. Sebagai contoh:

.state('A', {
  redirectTo: 'A.B'
})
BBlackwo
sumber
7

Sejak versi 1.0 dari ui-router, hook default telah diperkenalkan menggunakan IHookRegistry.onBefore () seperti yang ditunjukkan dalam contoh Substate Default Berbasis Data di http://angular-ui.github.io/ui-router/feature-1.0/ interfaces / transisi.ihookregistry.html # onbefore

// state declaration
{
  name: 'home',
  template: '<div ui-view/>',
  defaultSubstate: 'home.dashboard'
}

var criteria = {
  to: function(state) {
    return state.defaultSubstate != null;
  }
}
$transitions.onBefore(criteria, function($transition$, $state) {
  return $state.target($transition$.to().defaultSubstate);
});
ThmX
sumber
Pekerjaan semacam ini untuk saya, meskipun, saya harus mengubahnya (juga menggunakan ES6)$transitions.onBefore({ to: state => state.defaultSubstate != null }, trans => trans.router.stateService.target(trans.to().defaultSubstate));
yorch
3
app.config(function($stateProvider,$urlRouterProvider){

    $urlRouterProvider.when("/state","/state/sub-state");

    })
shubam yadav
sumber
1
Dapatkah Anda memberikan penjelasan tentang fungsi ini dan mengapa ini lebih baik daripada jawaban yang sudah ada?
Sama dengan
Solusi ini adalah yang termudah dan bekerja dengan baik untuk saya.
BuffMcBigHuge
Sejauh ini, ini adalah jawaban terbaik. Lebih ringkas daripada menggunakan peristiwa perubahan. Tidak perlu menambahkan paket. Saya tidak tahu bagaimana itu tidak jelas bagi siapa pun. Saya tidak tahu bagaimana jawaban yang diterima mendapat banyak suara positif.
CodeWarrior
1

Jika seseorang datang ke sini untuk mendapatkan jawaban tentang cara menerapkan pengalihan sederhana untuk suatu status dan, seperti yang terjadi pada saya, tidak memiliki kesempatan untuk menggunakan router baru ...

Jelas sekali lagi jika Anda bisa, jawaban @bblackwo bagus:

$stateProvider.state('A', {
  redirectTo: 'B',
});

Jika Anda tidak bisa, alihkan saja secara manual:

$stateProvider.state('A', {
  controller: $state => {
    $state.go('B');
  },
});

Saya harap ini membantu!

Jose Daniel Vivar Personat
sumber