Ricerca…
Osservazioni
All'interno del sottosistema dati di Meteor, una pubblicazione server e le relative sottoscrizioni client sono i principali meccanismi di trasporto reattivo e in tempo reale dei dati in cui i dati sottostanti sono costantemente sincronizzati tra il server e il client.
Abbonamento e pubblicazione di base
Innanzitutto, rimuovi l' autopublish
. autopublish
pubblica automaticamente l'intero database sul lato client, quindi non è possibile visualizzare gli effetti di pubblicazioni e abbonamenti.
Per rimuovere autopublish
:
$ meteor remove autopublish
Quindi puoi creare pubblicazioni. Di seguito è riportato un esempio completo.
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');
})
}
Pubblicazioni globali
Una pubblicazione globale non possiede un nome e non richiede una sottoscrizione dal client connesso e pertanto è disponibile per il client connesso non appena il client si connette al server.
Per ottenere ciò, si denomina semplicemente la pubblicazione come null
Meteor.publish(null, function() {
return SomeCollection.find();
})
Pubblicazioni con nome
Una pubblicazione con nome è quella che possiede un nome e deve essere esplicitamente sottoscritta dal client.
Considera questo codice lato server:
Meteor.publish('somePublication', function() {
return SomeCollection.find()
})
Il cliente deve richiederlo tramite:
Meteor.subscribe('somePublication')
Abbonamenti con ambito di modelli
Il sistema di templating di Meteor SpaceBars e il suo sottosistema di rendering sottostante Blaze si integrano in modo apparente con i metodi del ciclo di vita della pubblicazione in modo tale che un semplice codice di template possa sottoscrivere i propri dati, fermarsi e ripulire le proprie tracce durante l'abbattimento del template.
Per attingere a questo, è necessario iscriversi sull'istanza del modello, piuttosto che il simbolo Meteor
modo:
Prima imposta il modello
<template name="myTemplate">
We will use some data from a publication here
</template>
Quindi toccare il callback del ciclo di vita corrispondente
Template.myTemplate.onCreated(function() {
const templateInstance = this;
templateInstance.subscribe('somePublication')
})
Ora, quando questo modello viene distrutto, anche la pubblicazione verrà interrotta automaticamente.
Nota: i dati sottoscritti saranno disponibili per tutti i modelli.
Pubblica in una raccolta con nome lato client effimero.
Perché se devi mettere a punto ciò che è pubblicato.
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));
});
}
Creazione e risposta a un errore su una pubblicazione.
Sul server, è possibile creare una pubblicazione come questa. this.userId
è l'id dell'utente che ha effettuato l'accesso. Se nessun utente ha effettuato l'accesso, è possibile che si desideri generare un errore e rispondere ad esso.
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();
}
});
Sul client, puoi rispondere con il seguente.
Meteor.subscribe('protected_data', {
onError(err) {
if (err.error === 403) {
alert("Looks like you're not logged in");
}
},
});
File / importazioni / collezioni / Segreti crea un riferimento alla raccolta dei segreti come di seguito:
const Secrets = new Mongo.Collection('secrets');
Riattivare nuovamente la sottoscrizione a una pubblicazione
Un modello autorun può essere utilizzato per (ri) sottoscrivere una pubblicazione. Stabilisce un contesto reattivo che viene rieseguito ogni volta che i dati reattivi dipendono dai cambiamenti . Inoltre, un autorun viene eseguito sempre una volta (la prima volta che viene eseguito).
Gli autori di modelli sono normalmente inseriti in un metodo onCreated
.
Template.myTemplate.onCreated(function() {
this.parameter = new ReactiveVar();
this.autorun(() => {
this.subscribe('myPublication', this.parameter.get());
});
});
Questo verrà eseguito una volta (la prima volta) e impostato un abbonamento. Verrà quindi eseguito nuovamente ogni volta che cambia la variabile reattiva del parameter
.
Attendi nella vista Blaze mentre i dati pubblicati vengono recuperati
Modello JS code
Template.templateName.onCreated(function(){
this.subscribe('subsription1');
this.subscribe('subscription2');
});
Codice HTML modello
<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>
Convalida dell'account utente al momento della pubblicazione
A volte è una buona idea proteggere ulteriormente le tue pubblicazioni richiedendo un accesso utente. Ecco come si ottiene questo tramite 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 [];
}
});
Pubblica più cursori
Più cursori di database possono essere pubblicati dallo stesso metodo di pubblicazione restituendo una matrice di cursori.
I cursori "bambini" verranno considerati come join e non saranno reattivi.
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];
});
Simula il ritardo nelle pubblicazioni
Nel mondo reale, potrebbero verificarsi ritardi dei server e della connessione, per simulare ritardi nell'ambiente di sviluppo Meteor._sleepForMs(ms);
potrebbe essere usato
Meteor.publish('USER_DATA', function() {
Meteor._sleepForMs(3000); // Simulate 3 seconds delay
return Meteor.users.find({});
});
Unione di pubblicazioni
Le pubblicazioni possono essere unite sul client, dando origine a documenti di forma diversa all'interno di un singolo cursore. L'esempio seguente mostra in che modo una directory utente può pubblicare una quantità minima di dati pubblici per gli utenti di un'app e fornire un profilo più dettagliato per l'utente che ha effettuato l'accesso.
// 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
}});
});