Zoeken…


Opmerkingen

Binnen het datasubsysteem van Meteor zijn een serverpublicatie en de bijbehorende klantabonnementen de belangrijkste mechanismen van reactief, live datatransport waarbij de onderliggende gegevens constant worden gesynchroniseerd tussen de server en de client.

Basisabonnement en publicatie

Verwijder eerst autopublish . autopublish publiceert automatisch de hele database naar de client, waardoor de effecten van publicaties en abonnementen niet zichtbaar zijn.

autopublish verwijderen:

$ meteor remove autopublish

Vervolgens kunt u publicaties maken. Hieronder staat een volledig voorbeeld.

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

Wereldwijde publicaties

Een globale publicatie heeft geen naam en vereist geen abonnement van de verbonden client en is daarom beschikbaar voor de verbonden client zodra de client verbinding maakt met de server.

Om dit te bereiken, noemt men de publicatie eenvoudigweg als null

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

Benoemde publicaties

Een genoemde publicatie is er een die een naam bezit en waarop de klant zich expliciet moet abonneren.

Overweeg deze server side code:

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

De klant moet dit aanvragen door:

Meteor.subscribe('somePublication')

Sjabloonbereikabonnementen

Het standaard templating-systeem van Meteor Spacebars en het onderliggende rendering-subsysteem Blaze integreren naadloos met de methodes van de publicatielevenscyclus, zodat een eenvoudig stukje sjablooncode zich op zijn eigen gegevens kan abonneren, zijn eigen sporen kan stoppen en opruimen tijdens het afbreken van de sjabloon.

Om hierop in te spelen, moet men zich abonneren op de sjablooninstantie, in plaats van het Meteor symbool als volgt:

Stel eerst de sjabloon in

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

Tik vervolgens op de bijbehorende call voor de levenscyclus

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

Wanneer dit sjabloon wordt vernietigd, wordt de publicatie ook automatisch gestopt.

Opmerking: de gegevens waarop is geabonneerd, zijn beschikbaar voor alle sjablonen.

Publiceer in een tijdelijke client-side genaamd collectie.

Want als je moet afstemmen wat er wordt gepubliceerd.

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

Een fout in een publicatie maken en erop reageren.

Op de server kunt u een dergelijke publicatie maken. this.userId is de id van de gebruiker die momenteel is aangemeld. Als er geen gebruiker is aangemeld, wilt u mogelijk een foutmelding geven en erop reageren.

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

Op de client kunt u met het volgende reageren.

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

Bestand / invoer / collecties / Geheimen verwijst naar de geheimenverzameling zoals hieronder:

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

Reactief opnieuw abonneren op een publicatie

Een sjabloon autorun kan worden gebruikt om (opnieuw) in te schrijven op een publicatie. Het creëert een reactieve context die opnieuw wordt uitgevoerd wanneer reactieve gegevens afhankelijk zijn van wijzigingen . Bovendien wordt een autorun altijd één keer uitgevoerd (de eerste keer dat deze wordt uitgevoerd).

Sjabloonautoruns worden normaal gesproken in een onCreated methode geplaatst.

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

Dit wordt een keer (de eerste keer) uitgevoerd en een abonnement wordt ingesteld. Het zal dan opnieuw worden uitgevoerd wanneer de parameter reactieve variabele verandert.

Wacht in de Blaze-weergave terwijl gepubliceerde gegevens worden opgehaald

Sjabloon JS-code

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

HTML-sjablooncode

<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>

Gebruikersaccount valideren bij publiceren

Soms is het een goed idee om uw publicaties verder te beveiligen door een gebruikersaanmelding te vereisen. Hier is hoe je dit kunt bereiken via 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 [];
  }
});

Publiceer meerdere cursors

Meerdere databasecursors kunnen worden gepubliceerd vanuit dezelfde publicatiemethode door een reeks cursors te retourneren.

De cursors "kinderen" worden behandeld als joins en zijn niet reactief.

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

Simuleer vertraging in publicaties

In de echte wereld kunnen verbindings- en serververtragingen optreden om vertragingen in de ontwikkelingsomgeving Meteor._sleepForMs(ms); te simuleren Meteor._sleepForMs(ms); kan gebruikt worden

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

Publicaties samenvoegen

Publicaties kunnen op de client worden samengevoegd, wat resulteert in verschillend gevormde documenten binnen een enkele cursor. Het volgende voorbeeld geeft weer hoe een gebruikersmap een minimale hoeveelheid openbare gegevens voor gebruikers van een app kan publiceren en een meer gedetailleerd profiel voor de ingelogde gebruiker kan bieden.

// 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
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow