Backbone: router.navigate tidak memanggil router kecuali hash diubah

Dibuat pada 2 Okt 2011  ·  22Komentar  ·  Sumber: jashkenas/backbone

Saya mencoba menggunakan URL tanpa hashbangs yang menyebabkan beberapa kesedihan.

Saat saya menguji saya melakukan ini.

<a href="#" onclick="router.navigate('/albums/<%= album.id %>', true); return false;">Show</a>

URL diperbarui tetapi router saya tidak dipanggil. Awalnya saya pikir rutenya tidak cocok tetapi jika saya me-refresh halaman, rutenya berhasil cocok.

Kemudian saya mencoba ini:

<a href="#" onclick="router.navigate('/albums/<%= album.id %>', true);">Show</a>

Dan semuanya berfungsi dengan baik, sepertinya router hanya dipanggil jika hashchange dipicu.

Komentar yang paling membantu

Ini memang perilaku menarik dari router.navigate() yang pernah saya temui sebelumnya ketika mencoba memaksa rute untuk memuat ulang. Inilah yang akhirnya saya lakukan:

Backbone.history.loadUrl( Backbone.history.fragment )

Itu tidak _ secara eksplisit_ didokumentasikan sebagai bagian dari API, tetapi itu pasti menyelesaikan pekerjaan. Tampaknya masuk akal bagi saya bahwa router.navigate( 'current/path', true ) harus memicu penangan rute untuk dipanggil lagi.

Adakah orang lain yang peduli untuk ikut campur dalam hal ini?

Semua 22 komentar

Berfungsi jika saya menghapus /
Tebak itu harus sama persis dengan rute Anda

Ini memang perilaku menarik dari router.navigate() yang pernah saya temui sebelumnya ketika mencoba memaksa rute untuk memuat ulang. Inilah yang akhirnya saya lakukan:

Backbone.history.loadUrl( Backbone.history.fragment )

Itu tidak _ secara eksplisit_ didokumentasikan sebagai bagian dari API, tetapi itu pasti menyelesaikan pekerjaan. Tampaknya masuk akal bagi saya bahwa router.navigate( 'current/path', true ) harus memicu penangan rute untuk dipanggil lagi.

Adakah orang lain yang peduli untuk ikut campur dalam hal ini?

Saya mengalami masalah ini juga. Inilah kasus penggunaan khusus saya:

Saya menggunakan kueri media untuk menyediakan antarmuka responsif untuk semua ukuran layar. Pandangan saya memiliki beberapa elemen di dalamnya yang tidak menanggapi kueri media, jadi saya menulis sebuah fungsi untuk mendengarkan acara pengubahan ukuran dan merender ulang halaman jika perlu. Daripada merujuk dan memberikan pandangan individu, saya pikir saya hanya akan menelepon

router.navigate(Backbone.history.fragment, true)

Saya lebih suka tidak harus merujuk Backbone.history sama sekali. Akan lebih baik jika router memiliki metode refresh atau reload:

router.refresh(true);

Saya memiliki masalah yang sama. @Ansman dapatkah Anda menunjukkan apa rute Anda? Masalah saya adalah bahwa garis miring utama secara otomatis dihapus oleh riwayat ketika mendapatkan hash, karena ini adalah root default.

Ya -- Anda tidak boleh memiliki garis miring ... baik di rute Anda atau di panggilan navigasi() Anda. Yang mengatakan, ada komit pada master yang secara paksa menghapus semua garis miring, jadi ini seharusnya tidak lagi mengarah pada perilaku kereta.

Akhirnya, ya, router Anda seharusnya hanya menyala jika rutenya benar-benar telah diubah.

Saya ingin berpadu bahwa panggilan eksplisit ke router.navigate("route", true) harus memicu rute meskipun rute belum diubah di hash

@danroberts Tampaknya saat ini tidak mungkin untuk memaksa memicu rute jika hash tidak berubah. Saya mencoba router.navigate("route/", {trigger:true}); dan itu tidak berhasil. Retasan cepat adalah dengan memanggil router.route_name() .

@olalonde Saya telah menggunakan metode @wookiehangover di atas dengan hasil yang baik. Saya baru saja menulis fungsi khusus yang memeriksa apakah rute yang saya coba tuju sama dengan hash saat ini, dan kemudian memanggil router.navigate atau history.loadURL.

Tampaknya masuk akal bahwa ini bisa menjadi bagian dari array opsi, sesuatu seperti refresh:true jika Anda ingin memicu rute apa pun. Juga, mungkin pembaruan dokumentasi tampaknya berurutan, karena {trigger: true} secara logis akan memicu rute...

Inilah masalah yang saya miliki dengan menutup bug ini:

Poin kunci menggunakan tulang punggung adalah untuk menangani penguraian rute, dan kemudian memanggil fungsi berdasarkan rute. Tidak memiliki kemampuan untuk menentukan kasus di mana "reload" tidak masalah melalui backbone secara langsung, kita harus melakukan sesuatu untuk efek ini:

        if (url == window.location.pathname + window.location.search) {
            Backbone.history.loadUrl(url);
            return false;
        }
        else if (app.router.isHandled(url)) {
            Backbone.history.navigate(url, {
                trigger: true
            });
            return false;
        }

Apakah ini bekerja? ya, tapi rasanya ini adalah kasus penggunaan yang benar-benar valid yang akan menyenangkan untuk dimiliki di platform.

FYI saya melihat # 1214 sebelum utas ini dan memposting komentar yang sama.

Backbone Router tidak mengizinkan jenis tindakan ini karena ia mendengarkan peristiwa perubahan url untuk memicu tindakan yang dirutekan.

Anda perlu mencegat kontrol yang memicu tindakan dan mengatur ulang tindakan Router.

Saya membuat contoh jsFiddle di sini:
http://goo.gl/wPulo

dan posting blog di sini:
http://goo.gl/mJM2i

Mengalami masalah ini hari ini dan hanya ingin menambahkan 2 sen saya:

Sepertinya perilaku tidak intuitif yang ketika secara eksplisit mengatur trigger: true itu tidak akan memicu acara kecuali hash telah berubah.

Suara saya mendukung trigger: true memicu rute apa pun kondisinya.

Salah satu contoh dunia nyata adalah ketika Anda ingin menyegarkan halaman yang sedang Anda buka, itu tidak mungkin dilakukan dengan perilaku trigger: true .

+1 untuk metode KenPerkins atau yang serupa untuk diintegrasikan ke dalam router BB.

+1 untuk proses navigasi pada halaman yang sama jika { trigger: true } dilewatkan

Saya telah menghabiskan 3 jam untuk mencari tahu mengapa metode roter.navigate() tidak berfungsi pada aplikasi saya. Saya pikir, dokumen BB harus menyertakan pemberitahuan tentang masalah ini.

Solusi jelek tapi cepat saya adalah memanggil metode router.navigate() sebelum yang sebenarnya.

router.navigate();
router.navigate("app", true);

Untuk saat ini, itu berhasil. Tetapi jika ada opsi refresh:true , saya pasti akan menggunakannya...

Hanya meninggalkan pemikiran saya tentang ini karena ini adalah masalah yang baru saja saya temui hari ini. Tampaknya sangat tidak intuitif bahwa rute tidak dipanggil ketika Anda secara eksplisit meneruskan hash opsi {trigger: true} ke router.navigate. Saya ingin melihat penambahan opsi refresh:true seperti yang disarankan @onuradsay .

1 untuk kepraktisan @patrickod dan ide @onuradsay 's

+1. Kami masih dapat menerima acara tersebut dan kemudian menentukan di aplikasi kami apakah penyegaran diperlukan. Kami dapat mengetahuinya dengan banyak peretasan yang disebutkan di atas tetapi tidak terlalu bersih. Saya pikir perilaku ini cukup umum untuk dimasukkan ke dalam Router.

Aku takut itu tidak akan terjadi. Fakta bahwa orang-orang memintanya sebenarnya lebih mendorong untuk _menghapus_ trigger:true daripada memecat acara tanpa syarat. Mari saya jelaskan:

Acara di Backbone adalah tentang pemberitahuan saat status diubah. Sama seperti bagaimana dalam model, melakukan:

model.set({title: "Boom"})
model.set({title: "Boom"})

... tidak akan memicu peristiwa untuk kedua kalinya, karena tidak ada status yang diubah ... mencoba menavigasi ke lokasi tempat Anda berada _bukan_ perubahan status, dan tidak akan memicu peristiwa.

Jika Anda ingin mengaktifkan panggilan balik setiap kali tombol diklik -- cukup tambahkan panggilan balik. Atau jika Anda ingin menggunakan acara Backbone untuk melakukannya -- panggil saja object.trigger("myEvent")

Sepertinya alih-alih trigger:true itu harus dianggap benar dan memiliki opsi silent:false .

Jika kami tidak menambahkan fungsi ini, kami akan selalu melakukan sesuatu seperti ini di penangan tombol kami -

if (Backbone.history.fragment === 'foo') {
    Backbone.history.loadUrl(Backbone.history.fragment);
 } else {
     router.navigate('foo', {'trigger': true});
}

Terima kasih @dankantor untuk trik hebatnya!

Jika Anda harus melakukan kasus penggunaan ini (untuk memaksa memuat ulang halaman/hash yang sama), tidakkah Anda ingin Backbone.history.getFragment() alih-alih history.fragment sehingga Anda tidak menjangkau properti riwayat? Tampaknya lebih bersih.

Saya membuat metode Backbone.history.refresh untuk memaksa memuat ulang. Kemudian, di beberapa proyek, saya mengganti perilaku navigasi default untuk memuat ulang terlepas dari apakah hash telah berubah:

      _.extend(Backbone.History.prototype, {
            refresh: function() {
                this.loadUrl(this.fragment);
            }
        });

        var routeStripper = /^[#\/]/;
        var origNavigate = Backbone.History.prototype.navigate;
        Backbone.History.prototype.navigate = function (fragment, options) {
            var frag = (fragment || '').replace(routeStripper, '');
            if (this.fragment == frag)
                this.refresh();
            else
                origNavigate.call(this, fragment, options);
        };
Apakah halaman ini membantu?
0 / 5 - 0 peringkat

Masalah terkait

sarkasm picture sarkasm  ·  7Komentar

azizZaben picture azizZaben  ·  5Komentar

inf3rno picture inf3rno  ·  17Komentar

jashkenas picture jashkenas  ·  7Komentar

miguelpayet picture miguelpayet  ·  9Komentar