Facebook ชอบโหลดโพสต์ใหม่ใน meteor

ฉันกำลังอยู่ในขั้นตอนการเรียนรู้ดาวตก ฉันทำตามบทช่วยสอนเพื่อสร้างกล้องจุลทรรศน์ หากมีใครส่งโพสต์ดาวตก จะแสดงเทมเพลตใหม่ให้กับผู้ใช้ทุกคน สิ่งนี้อาจเป็นเรื่องที่น่ารำคาญมากหากมีโพสต์หลายร้อยโพสต์ ผู้ใช้จะกลับมาที่ด้านบนสุดของหน้าและติดตามว่าเขาอยู่ที่ไหน ฉันต้องการใช้สิ่งที่คล้ายกับสิ่งที่ facebook มี เมื่อเทมเพลตที่ส่งโพสต์ใหม่ไม่แสดงผล ปุ่มหรือลิงก์จะปรากฏขึ้น การคลิกจะทำให้เทมเพลตแสดงผลซ้ำและแสดงโพสต์ใหม่

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

Meteor.publish('posts', function(options) {
  var self = this, postHandle = null;

  var initializing = true;

  postHandle = Posts.find({}, options).observeChanges({
    added: function(id, post) {

      if (initializing){
          self.added('posts', id, post);
      } 
    },
    changed: function(id, fields) {
      self.changed('posts', id, fields);
    }
  });

  self.ready();
  initializing = false;
  self.onStop(function() { postHandle.stop(); });
});

นี่เป็นเส้นทางที่ถูกต้องหรือไม่? หากใช่ ฉันจะแจ้งเตือนผู้ใช้เมื่อมีโพสต์ใหม่ได้อย่างไร มิฉะนั้นจะมีวิธีใดที่ดีกว่าในการดำเนินการนี้

ขอบคุณ


person Guranjan Singh    schedule 10.07.2015    source แหล่งที่มา


คำตอบ (2)


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

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

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

// Within the template where you want to show your data
Template.myTemplate.onCreated(function() {
  var self = this;
  var options = null; // Define non-time options

  // Subscribe to the data so everything is loaded into the client
  // Include relevant options to limit data but exclude timestamps
  self.subscribe("posts", options);

  // Create and initialise a reactive variable with the current date
  self.loadedTime = new ReactiveVar(new Date());

  // Create a reactive variable to see when new data is available
  // Create an autorun for whenever the subscription changes ready() state
  // Ignore the first run as ready() should be false
  // Subsequent false values indicate new data is arriving
  self.newData = new ReactiveVar(false);
  self.autorun(function(computation) {
    if(!computation.firstRun) {
      if(!self.subscriptionsReady()) {
        self.newData.set(true);
      }
    }
  });
});

// Fetch the relevant data from that subscribed (cached) within the client
// Assume this will be within the template helper
// Use the value (get()) of the Reactive Variable
Template.myTemplate.helpers({
  displayedPosts = function() {
    return Posts.find({timestamp: {$lt: Template.instance().loadedTime.get()}});
  },

  // Second helper to determine whether or not new data is available
  // Can be used in the template to notify the user
  newData = function() {
    return Template.instance().newData.get();
});

// Update the Reactive Variable to the current time
// Assume this takes place within the template helper
// Assume you have button (or similar) with a "reload" class
Template.myTemplate.events({
  'click .reLoad' = function(event, template) {
    template.loadedTime.set(new Date());
  }
});

ฉันคิดว่านี่เป็นรูปแบบที่ง่ายที่สุดที่จะครอบคลุมทุกประเด็นที่คุณยกขึ้น มันจะซับซ้อนมากขึ้นหากคุณไม่มีการประทับเวลา คุณมีการสมัครสมาชิกหลายรายการ (จากนั้นจำเป็นต้องใช้ตัวจัดการการสมัครสมาชิก) ฯลฯ หวังว่านี่จะช่วยได้!

person Duncan Foster    schedule 10.07.2015
comment
ดูเหมือนจะไม่ทำงาน มันหยุดการเรนเดอร์ซ้ำ แต่ newData ไม่เคยถูกตั้งค่าเป็นจริง - person Guranjan Singh; 17.07.2015
comment
ขอโทษ. ดูเหมือนว่า subscriptionsReady() อาจไม่เกิดปฏิกิริยา (เอกสารไม่ชัดเจน) แต่ตัวช่วยเทมเพลตเสริมกลับเป็นเช่นนั้น ดังนั้นการทำงานอัตโนมัติจะไม่ถูกทริกเกอร์ คุณอาจจำเป็นต้องใช้เมธอด ready() บนตัวจัดการการสมัครสมาชิกหรือ onReady() โทรกลับภายในฟังก์ชันการสมัครสมาชิกแทน - person Duncan Foster; 20.07.2015

ดังที่ Duncan กล่าวในคำตอบของเขา ReactiveVar คือหนทางไป จริงๆ แล้วฉันได้ใช้หน้าฟีด Facebook ธรรมดาพร้อม meteor ซึ่งฉันแสดงโพสต์สาธารณะจากหน้าใดหน้าหนึ่ง ฉันใช้การเลื่อนแบบไม่มีที่สิ้นสุดเพื่อเพิ่มโพสต์ที่ด้านล่างของหน้าและจัดเก็บไว้ใน ReactiveVar ตรวจสอบแหล่งที่มาบน github ที่นี่ และการสาธิตสด ที่นี่ หวังว่ามันจะช่วยได้!

person Cristian    schedule 10.07.2015