Поиск…


замечания

В подсистеме данных Meteor публикация сервера и соответствующие подписки клиента являются основными механизмами реактивной передачи данных в реальном времени, когда базовые данные постоянно синхронизируются между сервером и клиентом.

Основная подписка и публикация

Сначала удалите autopublish . autopublish автоматически публикует всю базу данных на стороне клиента, поэтому эффекты публикаций и подписки не могут быть видны.

Чтобы удалить autopublish :

$ meteor remove autopublish

Затем вы можете создавать публикации. Ниже приведен полный пример.

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

Глобальные публикации

Глобальная публикация не имеет имени и не требует подписки от подключенного клиента, и поэтому она доступна подключенному клиенту, как только клиент подключается к серверу.

Чтобы добиться этого, можно просто назвать публикацию null

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

Названные публикации

Именованная публикация - это имя, которое имеет имя и должно быть явно подписано клиентом.

Рассмотрим этот код на стороне сервера:

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

Клиент должен запросить его:

Meteor.subscribe('somePublication')

Подписчики с подменю шаблонов

Система моделирования шаблонов Meteor Spacebars и ее базовая подсистема рендеринга Blaze без видимости интегрируются с методами жизненного цикла публикации, так что простая часть кода шаблона может подписываться на свои собственные данные, останавливать и очищать свои собственные трассы во время разрыва шаблона.

Чтобы воспользоваться этим, нужно подписаться на экземпляр шаблона, а не на символ Meteor :

Сначала настройте шаблон

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

Затем коснитесь соответствующего обратного вызова жизненного цикла

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

Теперь, когда этот шаблон будет уничтожен, публикация также будет остановлена ​​автоматически.

Примечание. Данные, на которые подписаны, будут доступны для всех шаблонов.

Публикация в эфемерной клиентской стороне.

Ибо, если вам нужно настроить то, что опубликовано.

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

Создание и реагирование на ошибку в публикации.

На сервере вы можете создать такую ​​публикацию. this.userId - это идентификатор пользователя, который в настоящий момент вошел в систему. Если ни один пользователь не вошел в систему, вам может потребоваться выбросить ошибку и ответить на нее.

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

На клиенте вы можете ответить следующим.

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

Файл / импорт / коллекции / Секреты создают ссылку на коллекцию секретов, как показано ниже:

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

Реактивировать повторную подписку на публикацию

Автозапуск шаблонов может использоваться для (пере) подписки на публикацию. Он устанавливает реактивный контекст, который повторно выполняется, когда любые реактивные данные зависят от изменений . Кроме того, автозапуск всегда выполняется один раз (при первом запуске).

onCreated шаблонов обычно помещается в метод onCreated .

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

Это будет запускаться один раз (первый раз) и настроить подписку. Затем он будет повторно запускаться всякий раз, когда изменяется переменная parameter .

Подождите в режиме Blaze, пока публикуются данные

Шаблон JS-кода

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

Шаблон HTML-кода

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

Проверка учетной записи пользователя при публикации

Иногда это хорошая идея для дальнейшей защиты ваших изданий, требуя входа пользователя в систему. Вот как вы достигаете этого через Метеор.

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

Публикация нескольких курсоров

Несколько курсоров базы данных могут быть опубликованы из одного метода публикации, возвращая массив курсоров.

Курсоры «дети» будут рассматриваться как объединения и не будут реагировать.

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

Моделировать задержку публикаций

В реальном мире могут возникнуть задержки соединения и сервера, чтобы имитировать задержки в среде разработки Meteor._sleepForMs(ms); может быть использован

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

Объединение публикаций

Публикации могут быть объединены на клиенте, в результате чего документы с разными формами формируются в пределах одного курсора. В следующем примере показано, как каталог пользователя может публиковать минимальное количество общедоступных данных для пользователей приложения и предоставлять более подробный профиль для зарегистрированного пользователя.

// 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
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow