Szukaj…


Uwagi

W podsystemie danych Meteor publikacja serwera i odpowiadające mu subskrypcje klientów są głównymi mechanizmami reaktywnego przesyłania danych na żywo, w których dane podstawowe są stale synchronizowane między serwerem a klientem.

Podstawowa subskrypcja i publikacja

Najpierw usuń automatyczne autopublish . autopublish automatycznie publikuje całą bazę danych po stronie klienta, więc efekty publikacji i subskrypcji nie są widoczne.

Aby usunąć automatyczne autopublish :

$ meteor remove autopublish

Następnie możesz tworzyć publikacje. Poniżej znajduje się pełny przykład.

import { Mongo } from 'meteor/mongo';
import { Meteor } from 'meteor/meteor';

const Todos = new Mongo.Collection('todos');

const TODOS = [
  { title: 'Create documentation' },
  { title: 'Submit to Stack Overflow' }
];

if (Meteor.isServer) {
  Meteor.startup(function () {
    TODOS.forEach(todo => {
      Todos.upsert(
        { title: todo.title },
        { $setOnInsert: todo }
      );
    });
  });

  // first parameter is a name.
  Meteor.publish('todos', function () {
    return Todos.find();
  });
}

if (Meteor.isClient) {
  // subscribe by name to the publication.
  Meteor.startup(function () {
    Meteor.subscribe('todos');
  })
}

Publikacje globalne

Publikacja globalna nie ma nazwy i nie wymaga subskrypcji od podłączonego klienta, dlatego jest dostępna dla podłączonego klienta, gdy tylko klient połączy się z serwerem.

Aby to osiągnąć, wystarczy po prostu nazwać publikację taką jak null

Meteor.publish(null, function() {
  return SomeCollection.find();
})

Nazwane publikacje

Publikacja nazwana to taka, która ma nazwę i musi zostać wyraźnie zasubskrybowana przez klienta.

Rozważ ten kod po stronie serwera:

Meteor.publish('somePublication', function() {
  return SomeCollection.find()
})

Klient musi o to poprosić:

Meteor.subscribe('somePublication')

Subskrypcje o zasięgu szablonowym

Domyślny system szablonów Meteor Paski kosmiczne i leżący u jego podstaw podsystem renderowania Blaze bez trudu integrują się z metodami cyklu życia publikacji, dzięki czemu prosty fragment kodu szablonu może subskrybować własne dane, zatrzymać i wyczyścić własne ślady podczas usuwania szablonu.

Aby się do tego przyłączyć, należy zasubskrybować instancję szablonu, a nie symbol Meteor :

Najpierw skonfiguruj szablon

<template name="myTemplate">
  We will use some data from a publication here
</template>

Następnie dotknij odpowiedniego wywołania zwrotnego cyklu życia

Template.myTemplate.onCreated(function() {
  const templateInstance = this;
  templateInstance.subscribe('somePublication')
})

Teraz, gdy ten szablon zostanie zniszczony, publikacja również zostanie automatycznie zatrzymana.

Uwaga: subskrybowane dane będą dostępne dla wszystkich szablonów.

Opublikuj w efemerycznej kolekcji o nazwie po stronie klienta.

Bo jeśli musisz dostosować to, co jest publikowane.

import { Mongo } from 'meteor/mongo';
import { Meteor } from 'meteor/meteor';
import { Random } from 'meteor/random';

if (Meteor.isClient) {
  // established this collection on the client only.
  // a name is required (first parameter) and this is not persisted on the server.
  const Messages = new Mongo.Collection('messages');
  Meteor.startup(function () {
    Meteor.subscribe('messages');
    Messages.find().observe({
      added: function (message) {
        console.log('Received a new message at ' + message.timestamp);
      }
    });
  })
}

if (Meteor.isServer) {
  // this will add a new message every 5 seconds.
  Meteor.publish('messages', function () {
    const interval = Meteor.setInterval(() => {
      this.added('messages', Random.id(), {
        message: '5 seconds have passed',
        timestamp: new Date()
      })
    }, 5000);
    this.added('messages', Random.id(), {
      message: 'First message',
      timestamp: new Date()
    });
    this.onStop(() => Meteor.clearInterval(interval));
  });
}

Tworzenie i reagowanie na błąd w publikacji.

Na serwerze możesz utworzyć taką publikację. this.userId to identyfikator użytkownika, który jest aktualnie zalogowany. Jeśli żaden użytkownik nie jest zalogowany, możesz chcieć this.userId błąd i odpowiedzieć na niego.

import Secrets from '/imports/collections/Secrets';

Meteor.publish('protected_data', function () {
  if (!this.userId) {
    this.error(new Meteor.Error(403, "Not Logged In."));
    this.ready();
  } else {
    return Secrets.find();
  }
});

Na kliencie możesz odpowiedzieć na następujące pytania.

Meteor.subscribe('protected_data', {
  onError(err) {
    if (err.error === 403) {
      alert("Looks like you're not logged in");
    }
  },
});

Plik / import / kolekcje / Sekrety tworzy odniesienie do kolekcji sekretów, jak poniżej:

const Secrets = new Mongo.Collection('secrets');

Reaktywne subskrybowanie publikacji

Szablon autorun może być użyty do (ponownego) subskrybowania publikacji. Ustanawia reaktywny kontekst, który jest ponownie uruchamiany za każdym razem, gdy jakiekolwiek reaktywne dane zależą od zmian . Ponadto autorun zawsze uruchamia się raz (przy pierwszym uruchomieniu).

Autoruny szablonów są zwykle umieszczane w metodzie onCreated .

Template.myTemplate.onCreated(function() {
  this.parameter = new ReactiveVar();
  this.autorun(() => {
    this.subscribe('myPublication', this.parameter.get());
  });
});

Uruchomi się to raz (po raz pierwszy) i skonfiguruje subskrypcję. Następnie będzie uruchamiany ponownie, gdy zmieni się zmienna reaktywna parameter .

Poczekaj w widoku Blaze na pobieranie danych opublikowanych

Kod JS szablonu

Template.templateName.onCreated(function(){
    this.subscribe('subsription1');
    this.subscribe('subscription2');
});

Kod HTML szablonu

<template name="templateName">
    {{#if Template.subscriptionsReady }}
        //your actual view with data. it can be plain HTML or another template
    {{else}}
        //you can use any loader or a simple header
        <h2> Please wait ... </h2>
    {{/if}}
</template>

Sprawdzanie poprawności konta użytkownika podczas publikowania

Czasami warto zabezpieczyć swoje publikacje, wymagając loginu użytkownika. Oto jak to osiągnąć przez Meteor.

import { Recipes } from '../imports/api/recipes.js';
import { Meteor } from 'meteor/meteor';

Meteor.publish('recipes', function() {
  if(this.userId) {
    return Recipe.find({});
  } else {
    this.ready();  // or: return [];
  }
});

Opublikuj wiele kursorów

Wiele kursorów bazy danych można opublikować z tej samej metody publikacji, zwracając tablicę kursorów.

Kursory „potomne” będą traktowane jak złączenia i nie będą reagować.

Meteor.publish('USER_THREAD', function(postId) {
  let userId   = this.userId;

  let comments = Comments.find({ userId, postId });
  let replies  = Replies.find({ userId, postId });

  return [comments, replies];
});

Symuluj opóźnienie w publikacjach

W prawdziwym świecie mogą wystąpić opóźnienia połączenia i serwera, aby zasymulować opóźnienia w środowisku programistycznym Meteor._sleepForMs(ms); może być użyty

Meteor.publish('USER_DATA', function() {
    Meteor._sleepForMs(3000); // Simulate 3 seconds delay
    return Meteor.users.find({});
});

Scalanie publikacji

Publikacje mogą być scalane na kliencie, w wyniku czego dokumenty o różnych kształtach znajdują się w obrębie jednego kursora. Poniższy przykład przedstawia, w jaki sposób katalog użytkownika może publikować minimalną ilość danych publicznych dla użytkowników aplikacji i zapewnia bardziej szczegółowy profil dla zalogowanego użytkownika.

// client/subscriptions.js  
Meteor.subscribe('usersDirectory');
Meteor.subscribe('userProfile', Meteor.userId());

// server/publications.js  
// Publish users directory and user profile

Meteor.publish("usersDirectory", function (userId) {
    return Meteor.users.find({}, {fields: {
        '_id': true,
        'username': true,
        'emails': true,
        'emails[0].address': true,

        // available to everybody
        'profile': true,
        'profile.name': true,
        'profile.avatar': true,
        'profile.role': true
    }});
});
Meteor.publish('userProfile', function (userId) {
    return Meteor.users.find({_id: this.userId}, {fields: {
        '_id': true,
        'username': true,
        'emails': true,
        'emails[0].address': true,
    
        'profile': true,
        'profile.name': true,
        'profile.avatar': true,
        'profile.role': true,
    
        // privately accessible items, only availble to the user logged in
        'profile.visibility': true,
        'profile.socialsecurity': true,
        'profile.age': true,
        'profile.dateofbirth': true,
        'profile.zip': true,
        'profile.workphone': true,
        'profile.homephone': true,
        'profile.mobilephone': true,
        'profile.applicantType': true
    }});
});


Modified text is an extract of the original Stack Overflow Documentation
Licencjonowany na podstawie CC BY-SA 3.0
Nie związany z Stack Overflow