จะเปลี่ยนเค้าโครงเทมเพลตขึ้นอยู่กับนิพจน์ได้อย่างไร เตารีดเราเตอร์

แอพของฉันมีเลย์เอาต์หลายแบบสำหรับความต้องการที่แตกต่างกัน และฉันต้องการเลือกแบบไดนามิก ตัวอย่างเช่น ขึ้นอยู่กับพารามิเตอร์ GET หรือหากผู้ใช้เข้าสู่ระบบ

ฉันจะทำเช่นนี้ได้อย่างไร?


person Vitalii Del Vorobioff    schedule 26.02.2014    source แหล่งที่มา
comment
โดยส่วนตัวแล้ว ฉันจะย้ายตรรกะเล็กน้อยนี้ไปที่ template (โดยใช้ {{#if cond}} ... {{else}} ... {{/if}} และสื่อสารเงื่อนไขโดยใช้ data ที่มีอยู่ใน iron-router มีเหตุผลใดๆ หรือไม่ นอกเหนือจากการรักษาเทมเพลตที่ไม่ใช้ตรรกะโดยสิ้นเชิง คุณไม่ได้ใช้แนวทางนี้เหรอ?   -  person musically_ut    schedule 26.02.2014
comment
คุณใช้ Iron Router หรือแพ็คเกจเราเตอร์อื่นๆ อยู่แล้วใช่หรือไม่?   -  person Serkan Durusoy    schedule 26.02.2014
comment
จาก ปัญหานี้ ดูเหมือนว่าการกำหนดค่า layoutTemplate แบบไดนามิกไม่ได้เกิดขึ้นในขณะนี้ งาน. ฉันลองเปลี่ยนลำดับหลายครั้งในการกำหนดเทมเพลตอย่างมีเงื่อนไขใน before hook ทั้งใน Router.configure และในเส้นทางเฉพาะ การทดลองเหล่านั้นไม่ได้ผลเลย   -  person David Weldon    schedule 27.02.2014


คำตอบ (4)


คุณสามารถเปลี่ยนโครงร่างเทมเพลตแบบไดนามิกได้โดยใช้ this.router.layout() จากภายใน before hook (และอาจเป็น hook อื่น ๆ ) มันถูกซ่อนไว้เล็กน้อยและมีแนวโน้มที่จะเปลี่ยนแปลง แต่นี่คือวิธีที่ฉันสามารถเปลี่ยนเค้าโครงเทมเพลต ขึ้นอยู่กับว่าผู้ใช้เข้าสู่ระบบหรือไม่:

Router.configure({
    layoutTemplate: "defaultLayout",
    before: function (pause) {
        if(!Meteor.user()) {
            // render the login template but keep the url in the browser the same
            this.router.layout("loginLayout");
            this.render('login');

            // pause the rest of the before hooks and the action function
            pause();
        }else{
            //Here we have to change the layoutTemplate back to the default
            this.router.layout("defaultLayout");
        }
    }
});

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

person Dsyko    schedule 18.04.2014
comment
เพียงทราบถึงผู้อุปถัมภ์ เมื่อเร็วๆ นี้ iron:router ได้แทนที่ pause() ด้วย this.next() ดังนั้นโค้ดนี้จะไม่ทำงานหากไม่มีการแก้ไข: stackoverflow.com/questions/26629835/ - person James M. Lay; 22.02.2015

แก้ไข เนื่องจากผู้เขียนแก้ไขคำถามที่นี่ และข้อกำหนดของ iron:router ก็เปลี่ยนแปลงไปตามกาลเวลา ฉันจึงตัดสินใจรีเฟรชคำตอบนี้เล็กน้อยเพื่อป้องกันความสับสน

ดูเอกสารประกอบเกี่ยวกับการใช้แพ็คเกจ iron:router ได้ที่นี่

มีคำตอบที่เป็นไปได้สองสามข้อสำหรับคำถามนี้ ขึ้นอยู่กับประเภทของ "พารามิเตอร์"

โดยทั่วไปแหล่งความรู้หลักจะเป็น path เนื่องจากผู้ใช้ไม่จำเป็นต้องคาดหวังว่าเค้าโครงเพจจะมีการเปลี่ยนแปลงหาก path ยังคงเหมือนเดิม ในกรณีนี้ สิ่งนี้ค่อนข้างง่าย เพราะสิ่งเดียวที่คุณต้องมีคือการกำหนดเส้นทางที่เหมาะสม:

Router.route('/some/path/', {
  layoutTemplate: 'myFirstLayoutTemplate'
});

Router.route('/another/path/', {
  layoutTemplate: 'mySecondLayoutTemplate'
});

หากคุณต้องการการควบคุมที่ละเอียดยิ่งขึ้น คุณสามารถเลือกเค้าโครงด้วยตนเองในฮุก action ที่กำหนดให้กับเส้นทางที่กำหนดได้เสมอ:

Router.route('/some/path', {
  /* ... */
  action: function () {
    if (Meteor.user()) { // check if user is logged in
      this.layout('loggedInUserLayout');
    } else {
      this.layout('someDefaultLayout');
    }
    // you need this because otherwise the router
    // will not render your templates
    this.render();
  }
});

โปรดทราบว่า action hook ทำงานภายในการคำนวณ และเนื่องจาก Meteor.user() เป็นแหล่งข้อมูลที่มีปฏิกิริยา เพจของคุณจะถูกเรนเดอร์ใหม่ทุกครั้งที่ผู้ใช้เข้าสู่ระบบ / ออกจากระบบ

ดูรายละเอียดเพิ่มเติมเกี่ยวกับเค้าโครงได้ ที่นี่

person Tomasz Lenarcik    schedule 26.02.2014
comment
ขอบคุณ! สำหรับผู้ที่ต้องการหลีกเลี่ยงการใช้ this ก็สามารถใช้ได้เช่นกัน: Router.current().layout('loggedInUserLayout') มีประโยชน์สำหรับผู้ที่ใช้ฟังก์ชันลูกศรเช่น - person Bart S; 25.05.2021

ปัจจุบัน Meteor ไม่มีความสามารถในการเรนเดอร์เทมเพลตแบบไดนามิกบนเซิร์ฟเวอร์ก่อนที่จะให้บริการแก่ลูกค้า แต่จะทำหน้าที่รวมกลุ่มทั้งหมดเข้าด้วยกันแทน

ดังนั้นภายในบันเดิลนั้น คุณจึงสร้างเทมเพลตและใช้งานโดยขึ้นอยู่กับการกระทำของผู้ใช้ เส้นทาง URL พารามิเตอร์เซสชัน ฯลฯ

ดู Iron Router ซึ่งจะช่วยคุณได้

นอกจากนี้ยังมีการสนทนาอย่างต่อเนื่องในกลุ่ม Google meteor-talk และรายการบนกระดาน trello แผนงานดาวตก

person Serkan Durusoy    schedule 26.02.2014

ฉันจะทิ้งสิ่งนี้ไว้ที่นี่ ตั้งแต่ปี 2019 และใช้งานได้หลังจากประสบปัญหาบางอย่าง...

Router.route('/', function () {

    Router.current().layout("applicationLayoutEmpty");
    this.render('landing', {to: 'content'});

    if(Meteor.userId()){
        Router.go("/social");
    }

});

สิ่งมหัศจรรย์อยู่ใน: Router.current().layout("applicationLayoutEmpty");

โดยจะใช้ชุดเริ่มต้นใน main.js เมื่อคุณกำหนดค่า IronRouter แต่สามารถใช้ได้แม้ในหน้าต่างเบราว์เซอร์ของคุณ ลองใช้เลย!

person Andy    schedule 02.03.2019