Facebook suka memuat postingan baru di meteor

Saya sedang dalam proses belajar meteor. Saya mengikuti tutorial membuat mikroskop. Jika seseorang mengirimkan postingan, meteor akan merender ulang template untuk semua pengguna. Hal ini bisa sangat mengganggu jika ada ratusan postingan maka pengguna akan kembali ke bagian atas halaman dan kehilangan jejak di mana dia berada. Saya ingin menerapkan sesuatu yang mirip dengan apa yang dimiliki facebook. Ketika postingan baru dikirimkan, template tidak dirender, tombol atau link akan muncul. Mengkliknya akan menyebabkan template dirender ulang dan menampilkan postingan baru.

Saya sedang berpikir untuk menggunakan observeChanges pada koleksi untuk mendeteksi perubahan apa pun dan itu menghentikan halaman untuk menampilkan postingan baru tetapi satu-satunya cara untuk menunjukkannya adalah dengan memuat ulang halaman.

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

Apakah ini jalan yang benar untuk diambil? Jika ya, bagaimana cara memberi tahu pengguna tentang postingan baru? Jika tidak, cara apa yang lebih baik untuk menerapkan ini?

Terima kasih


person Guranjan Singh    schedule 10.07.2015    source sumber


Jawaban (2)


Ini adalah pertanyaan rumit namun juga berharga karena berkaitan dengan pola desain yang dapat diterapkan dalam banyak kasus. Salah satu aspek kuncinya adalah ingin mengetahui adanya data baru tetapi tidak ingin (belum) menunjukkannya kepada pengguna. Kita juga dapat berasumsi bahwa ketika pengguna ingin melihat datanya, mereka mungkin tidak ingin menunggu data tersebut dimuat ke klien (seperti Facebook). Artinya, klien masih perlu menyimpan data dalam cache saat data tersebut tiba, hanya saja tidak langsung menampilkannya.

Oleh karena itu, Anda mungkin tidak ingin membatasi data yang ditampilkan dalam publikasi - karena ini tidak akan mengirimkan data ke klien. Sebaliknya, Anda ingin mengirim semua data (relevan) ke klien dan menyimpannya di cache hingga siap.

Cara termudah adalah dengan memiliki stempel waktu di data Anda untuk digunakan. Anda kemudian dapat memasangkannya dengan Variabel Reaktif untuk hanya menambahkan dokumen baru ke kumpulan tampilan Anda ketika Variabel Reaktif itu berubah. Sesuatu seperti ini (kode mungkin ada di file yang berbeda):

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

Saya rasa ini adalah pola paling sederhana untuk mencakup semua poin yang Anda ajukan. Ini menjadi lebih rumit jika Anda tidak memiliki stempel waktu, Anda memiliki banyak langganan (kemudian perlu menggunakan pegangan langganan) dll. Semoga ini bisa membantu!

person Duncan Foster    schedule 10.07.2015
comment
Ini sepertinya tidak berhasil. Itu menghentikan rendering ulang tetapi newData tidak pernah disetel ke true. - person Guranjan Singh; 17.07.2015
comment
Maaf. Sepertinya subscriptionsReady() mungkin tidak reaktif (dokumennya tidak jelas) tetapi pembantu template pelengkapnya. Oleh karena itu, autorun tidak akan terpicu. Sebagai gantinya, Anda mungkin perlu menggunakan metode ready() pada pegangan langganan atau panggilan balik onReady() dalam fungsi berlangganan. - person Duncan Foster; 20.07.2015

Seperti yang dikatakan Duncan dalam jawabannya, ReactiveVar adalah cara yang tepat. Saya sebenarnya telah menerapkan halaman feed facebook sederhana dengan meteor tempat saya menampilkan postingan publik dari halaman tertentu. Saya menggunakan gulir tak terbatas untuk terus menambahkan posting ke bagian bawah halaman dan menyimpannya di ReactiveVar. Periksa sumbernya di github di sini dan demo langsungnya di sini. Semoga bisa membantu!

person Cristian    schedule 10.07.2015