เราเตอร์ Meteor Iron ไม่ทำงานบนลิงก์บางลิงก์

ฉันมีเส้นทางเช่นนี้:

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.");
            })
        ];
    }
});

... และฉันกำลังคลิกลิงก์ในเทมเพลตดังนี้:

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

ฉันได้รับข้อความ 'เส้นทางกล่องวิ่งได้โอเค' ข้อความ แต่ด้วยเหตุผลบางประการที่หน้าเว็บไม่นำทางไปยัง URL ที่ระบุ ฉันได้เพิ่มโค้ด console.log ใน funciton ที่ทำงานเมื่อมีการเรนเดอร์ 'boxCanvasTpl' แต่สิ่งเหล่านี้ไม่แสดงในคอนโซลของเบราว์เซอร์ ดูเหมือนว่ามีบางสิ่งที่อยู่ระหว่างนั้นกำลังหยุดเทมเพลเคตจากการเรนเดอร์ซ้ำ แต่ไม่สามารถวางนิ้วลงบนมันได้ - มีความคิดเห็นใดบ้าง


person JoeTidee    schedule 13.06.2015    source แหล่งที่มา
comment
ใช้งานได้หรือไม่หากคุณลบ subscribe callbacks ทั้งสองออก   -  person David Weldon    schedule 14.06.2015
comment
การทดสอบนี้ทำได้ยากเนื่องจากหน้าที่มีลิงก์ดังกล่าวคือหน้าที่ฉันพยายามนำทางไป นี่จะเป็นปัญหาหรือไม่ เช่น ถ้าฉันอยู่บน /box?box=111 และพยายามนำทางไปยัง /box?box=123 - เป็นไปได้ไหมที่ฟังก์ชั่น 'onRendered' จะไม่ถูกเรียกใช้ซ้ำ   -  person JoeTidee    schedule 14.06.2015
comment
ฉันสับสนเล็กน้อยกับสิ่งที่คุณพยายามทำที่นี่ คุณมีพารามิเตอร์ใน URL (?box=123) แต่คุณไม่มีรหัสใด ๆ สำหรับการเข้าถึงพารามิเตอร์ URL เหล่านั้นโดยใช้ this.params - stackoverflow.com/questions/23050664/ และใช่ ถ้าคุณใส่ console.log ภายใน Template.boxCanvasTpl.onRendered() และ มันไม่แสดงขึ้นมา หมายความว่าเทมเพลตนั้นไม่ได้ถูกเรนเดอร์ (หรือเรนเดอร์ใหม่ ในกรณีของคุณ) Guh ฉันเกลียดเกลียดเกลียดการจัดรูปแบบในความคิดเห็น Stack Overflow ...   -  person fuzzybabybunny    schedule 14.06.2015
comment
@fuzzybabybunny ฉันใช้ Router.current().params.query.box นอกเราเตอร์ (ในฟังก์ชัน Template.onRendered ของฉัน) แต่นี่ไม่เกี่ยวข้องกับปัญหา   -  person JoeTidee    schedule 14.06.2015
comment
อ่า แต่มันเกี่ยวข้องกัน เนื่องจาก onRendered() ไม่เริ่มทำงาน ดังนั้นพารามิเตอร์ของคุณจึงไม่ได้รับการยอมรับ   -  person fuzzybabybunny    schedule 14.06.2015
comment
ในคำถามนี้ พารามิเตอร์ไม่ได้ทำให้เกิดปัญหา   -  person JoeTidee    schedule 14.06.2015


คำตอบ (1)


มีคุณสมบัติบางอย่างของ Iron Router ที่คุณต้องระวัง

สมมติว่าผู้ใช้อยู่ใน /boxes แล้ว และมีเทมเพลต box ที่แสดงผลสำหรับเส้นทางนั้น ถ้าคุณ:

  • คลิกที่ลิงค์ <a href="/th/boxes?box=123">Click Me</a>

or

  • คลิกที่ลิงค์ <a href="/th{{pathFor 'box'}}">Click Me</a>

Iron Router จะไม่เรนเดอร์เทมเพลตซ้ำเนื่องจากมีอยู่แล้วบนเพจ นอกจากนี้ จะไม่แสดงเทมเพลตซ้ำหากเทมเพลต box เป็นเทมเพลตบางส่วนที่ได้แสดงผลแล้วบนเพจที่คุณอยู่และยังมีอยู่ในเพจที่คุณต้องการนำทางไปด้วย

เนื่องจากไม่มีการเรนเดอร์ซ้ำ โค้ดใดๆ ที่คุณมีใน Template.box.onRendered จะไม่ทำงานอีกครั้งเช่นกัน

ลักษณะการทำงานนี้พบบ่อยที่สุดในเทมเพลต layout, header และ footer ของคุณ สำหรับผู้ใช้จำนวนมาก เทมเพลตเหล่านี้ใช้กับทุกหน้าของเว็บไซต์ โดยไม่คำนึงถึงเส้นทาง เนื่องจากเทมเพลตเค้าโครง ส่วนหัว และส่วนท้ายถูกแสดงผลในการเข้าชมไซต์ครั้งแรกของบุคคล จึงจะไม่ถูกเรนเดอร์ซ้ำอีกหากผู้ใช้ตัดสินใจที่จะนำทางไปยังส่วนอื่นๆ ของไซต์โดยใช้เทมเพลตเดียวกัน ดังนั้นโค้ด ภายใน Template.layout/header/footer.onRendered จะไม่ทำงาน

โปรดทราบด้วย - แม้ว่าตัวช่วย Spacebars แบบโต้ตอบจะเปลี่ยนรูปลักษณ์ทางกายภาพของเค้าโครง / ส่วนหัว / ส่วนท้าย แต่ก็ไม่เข้าข่ายเป็น render จริง ดังนั้นการอัปเดตแบบโต้ตอบในเทมเพลตจึงไม่ทริกเกอร์การเรียกกลับ onRendered

การไม่มีการเรนเดอร์ซ้ำเป็นสิ่งที่ทำให้ Meteor รู้สึก "เร็ว"

แก้ไข

พยายามเขียนโค้ดในรูปแบบที่โต้ตอบและขับเคลื่อนด้วยเหตุการณ์ พยายามอย่าคิดมากเกินไปในแง่การเรนเดอร์/การเรนเดอร์ซ้ำ

  1. คุณไปที่ /box
  2. คุณคลิกลิงก์สำหรับ /box?box=2342
  3. รับพารามิเตอร์หรือแบบสอบถามของคุณใน Iron Router

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

  1. ใน Iron Router ใช้ข้อมูลจากพารามิเตอร์หรือแบบสอบถามเพื่อตั้งค่า data context สำหรับเทมเพลต

  2. ดึงข้อมูลจากบริบทข้อมูลตามต้องการภายในการโทรกลับ .onRendered, .events และ .helpers ของเทมเพลต

  3. ตั้งค่า Session vars ตามความจำเป็น และใช้ในตัวช่วยเพื่อให้มีการเปลี่ยนแปลงที่เกิดขึ้นกับเพจโดยไม่ต้องเรนเดอร์เทมเพลตอีกครั้ง นอกจากนี้ ใช้เหตุการณ์เพื่อทริกเกอร์การอัปเดตเซสชันเพื่อทริกเกอร์การเปลี่ยนแปลงที่เกิดขึ้นกับเพจอีกครั้ง

ลองสิ่งนี้:

หลังจากนั้น ให้ไปที่ /test?BUNNIES=lalalala

ตรวจสอบบันทึกของคอนโซล

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);
  }

});

เราเตอร์.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')
    ];
  }
});

วิธีการเขียนเราเตอร์ที่สะอาดยิ่งขึ้น

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
ขอบคุณสำหรับสิ่งนี้ - ฉันสันนิษฐานว่าเป็นกรณีของเขา หากฉันมีฟังก์ชันที่เรนเดอร์เพจ (โดยใช้ Blaze.renderWithData ฯลฯ) ฉันจะทริกเกอร์ฟังก์ชันนั้นให้ทำงานจาก Iron Router ได้อย่างไร - person JoeTidee; 14.06.2015
comment
ฉันไม่สามารถให้เทมเพลตนี้เปิดใช้งานได้ ดังนั้น ฉันเพียงต้องการทริกเกอร์ฟังก์ชันที่จะแสดงผลเทมเพลตตามความต้องการ - person JoeTidee; 14.06.2015
comment
เราเตอร์ที่ฉันตั้งค่าไว้จะเรนเดอร์เทมเพลตใหม่ทุกครั้งที่เส้นทางเปลี่ยนไป (เช่น จาก /test?box=1234 ถึง` /test?box=0987`) ไม่ว่าคุณจะเลือกใช้ Reactive Vars หรือไม่ก็ขึ้นอยู่กับคุณ - person fuzzybabybunny; 14.06.2015
comment
ฉันยังได้เพิ่มวิธีการเขียนฟังก์ชันเราเตอร์ที่สะอาดตายิ่งขึ้น เนื่องจากวิธีนี้ทำให้คุณสามารถกำหนดลำดับที่ Iron Router กำลังทำสิ่งต่าง ๆ ได้อย่างชัดเจน (ขั้นแรกจะทำการ waitOn จากนั้นจึงตั้งค่าข้อมูล และสุดท้ายคือการดำเนินการของการเรนเดอร์) - person fuzzybabybunny; 14.06.2015