Meteor Iron Router tidak berfungsi pada tautan tertentu

Saya memiliki rute seperti ini:

Router.route('/box', function () {
    this.render('boxCanvasTpl');
},{
    name: 'box',
    layoutTemplate: 'appWrapperLoggedInTpl',
    waitOn: function() {
        console.log("Box route ran ok.");
        return [
            Meteor.subscribe('item_ownership_pub', function() {
                console.log("subscription 'item_ownership_pub' is ready.");
            }),
            Meteor.subscribe('my_items', function() {
                console.log("subscription 'my_items' is ready.");
            })
        ];
    }
});

...dan saya mengklik link di Template seperti ini:

<a href="/id/box?box=123" class="box-num-items">My Link</a>

Saya menerima pesan 'Rute kotak berjalan dengan baik.' pesan, tetapi beberapa alasan halaman tidak mengarah ke URL yang diberikan. Saya telah menambahkan kode console.log di fungsi yang dijalankan ketika 'boxCanvasTpl' dirender, tetapi ini tidak muncul di konsol browser. Tampaknya ada sesuatu di antara keduanya yang menghentikan rendering ulang template, tetapi saya tidak dapat menjelaskannya - ada ide?


person JoeTidee    schedule 13.06.2015    source sumber
comment
Apakah ini berfungsi jika Anda menghapus kedua panggilan balik subscribe?   -  person David Weldon    schedule 14.06.2015
comment
Ini sulit untuk diuji karena halaman yang berisi link yang disebutkan di atas adalah halaman yang saya coba navigasikan. Apakah ini masalahnya, yaitu jika saya berada di /box?box=111 dan mencoba menavigasi ke /box?box=123 - apakah fungsi 'onRendered' tidak dapat dijalankan kembali?   -  person JoeTidee    schedule 14.06.2015
comment
Saya sedikit bingung dengan apa yang Anda coba lakukan di sini. Anda memiliki parameter di URL (?box=123) tetapi Anda tidak memiliki kode apa pun untuk mengakses parameter URL tersebut menggunakan this.params - stackoverflow.com/questions/23050664/ Dan ya, jika Anda memasukkan console.log di dalam Template.boxCanvasTpl.onRendered() dan itu tidak muncul, itu berarti template tidak dirender (atau dirender ulang, dalam kasus Anda). Guh, aku benci benci format di komentar Stack Overflow...   -  person fuzzybabybunny    schedule 14.06.2015
comment
@fuzzybabybunny Saya menggunakan Router.current().params.query.box di luar Router (dalam fungsi Template.onRendered saya), tetapi ini tidak relevan dengan masalahnya.   -  person JoeTidee    schedule 14.06.2015
comment
Ah, tapi ini relevan, karena onRendered() tidak diaktifkan sehingga parameter Anda tidak dikenali.   -  person fuzzybabybunny    schedule 14.06.2015
comment
Dalam pertanyaan khusus ini, parameter tidak menyebabkan masalah.   -  person JoeTidee    schedule 14.06.2015


Jawaban (1)


Ada beberapa sifat Iron Router yang perlu Anda waspadai.

Katakanlah pengguna saat ini sudah menggunakan /boxes dan ada templat box yang merender jalur tersebut. Jika kamu:

  • klik tautan <a href="/id/boxes?box=123">Click Me</a>

or

  • klik tautan <a href="/id{{pathFor 'box'}}">Click Me</a>

Iron Router TIDAK akan merender ulang template karena sudah ada di halaman. Ini juga TIDAK akan merender ulang templat jika templat box merupakan sebagian templat yang sudah dirender pada laman yang Anda buka dan juga ada pada laman yang ingin Anda navigasikan.

Karena tidak dirender ulang, kode apa pun yang Anda miliki di dalam Template.box.onRendered juga tidak akan berjalan lagi.

Perilaku ini paling umum terjadi pada templat layout, header, dan footer Anda. Bagi banyak pengguna, templat ini digunakan untuk semua halaman situs web, apa pun jalurnya. Karena templat tata letak, header, dan footer dirender pada kunjungan pertama seseorang ke situs, maka templat tersebut tidak akan dirender ulang lagi jika pengguna memutuskan untuk menavigasi ke bagian lain situs menggunakan templat yang sama, jadi kodenya di dalam Template.layout/header/footer.onRendered tidak akan menyala.

Perhatikan juga - meskipun pembantu Spacebars reaktif mengubah tampilan fisik tata letak/header/footer, itu tidak memenuhi syarat sebagai render sebenarnya, jadi pembaruan reaktif pada templat tidak memicu panggilan balik onRendered.

Kurangnya rendering ulang inilah yang membuat Meteor terasa "tajam".

EDIT

Cobalah membuat kode dengan gaya reaktif dan didorong oleh peristiwa. Usahakan untuk tidak terlalu memikirkan dalam artian render/render ulang.

  1. Anda pergi ke /box
  2. Anda mengeklik tautan untuk /box?box=2342
  3. Dapatkan parameter atau kueri Anda di Iron Router

https://github.com/iron-meteor/iron-router/blob/devel/Guide.md#route-parameters

  1. Di Iron Router gunakan data dari params atau kueri untuk menyetel data context untuk templat.

  2. Ambil hal-hal dari konteks data sesuai kebutuhan di dalam callback .onRendered, .events, dan .helpers template.

  3. Tetapkan var Sesi seperlunya dan gunakan dalam pembantu untuk memberikan perubahan reaktif pada halaman tanpa harus merender ulang templat. Gunakan juga peristiwa untuk memicu pembaruan pada vars sesi untuk, sekali lagi, memicu perubahan reaktif pada halaman.

Coba ini:

setelah itu, buka /test?BUNNIES=lalalala

periksa log konsol

test.html

<template name="test">

    {{myData}}

</template>

test.js

Template.test.helpers({

  myData: function() {
    console.log("data context accessed from test.helpers: ", this);
    console.log("this.BUNNIES accessed from test.helpers: ", this.BUNNIES);
    return this.BUNNIES;
  }

});

Template.test.onRendered(function() {

  console.log("data context accessed from test.onRendered: ", this.data);

});

Template.test.events({

  'click': function(){
    console.log("data accessed from test.events: ", this);
  }

});

router.js

Router.route('/test', function() {
  console.log("routed!");
  this.render('test');

}, {
  name: 'test',
  data: function(){
    //here I am setting the data context
    // for /test?BUNNIES=1234
    var query = this.params.query;
    console.log("query: ", query);

    return query;
  },
  waitOn: function() {
    console.log("waitOn is running (should see this message once for each subscription)");
    return [
      Meteor.subscribe('item_ownership_pub'),
      Meteor.subscribe('my_items')
    ];
  }
});

cara menulis router yang jauh lebih bersih

Router.route('/test', {
  waitOn: function() {
    console.log("waitOn is running (should see this message once for each subscription");
    return [
      Meteor.subscribe('item_ownership_pub'),
      Meteor.subscribe('my_items')
    ];
  },
  data: function(){
    var query = this.params.query;
    console.log("query: ", query);
    return query;
  },
  action: function(){
    console.log("this will re-render if url params changed");
    this.render();
  }
})
person fuzzybabybunny    schedule 14.06.2015
comment
Terima kasih untuk ini - saya berasumsi bahwa itulah masalahnya. Jika saya memiliki fungsi yang merender halaman (menggunakan Blaze.renderWithData, dll.), bagaimana cara memicu fungsi tersebut agar dijalankan dari Iron Router? - person JoeTidee; 14.06.2015
comment
Saya tidak dapat membuat template ini menjadi reaktif, oleh karena itu saya hanya ingin memicu fungsi yang akan merender template sesuai permintaan. - person JoeTidee; 14.06.2015
comment
Router yang saya siapkan akan merender ulang templat setiap kali jalurnya berubah. (yaitu dari /test?box=1234 hingga` /test?box=0987`). Apakah Anda memilih untuk menggunakan vars reaktif, itu terserah Anda. - person fuzzybabybunny; 14.06.2015
comment
Saya juga menambahkan cara penulisan fungsi router yang lebih bersih karena dengan cara ini Anda dapat menentukan secara visual urutan apa yang dilakukan Iron Router (pertama-tama melakukan waitOn, kemudian mengatur data, dan terakhir melakukan tindakan rendering) - person fuzzybabybunny; 14.06.2015