Spec-Zone.ru › Marionette.js 3

Backbone Radio

Backbone Radio предоставляет простую поддержку ряда шаблонов обмена сообщениями для Backbone и Marionette. Это реализовано с помощью двух основных конструкций:

  • События - запускают события на глобальном объекте
  • Запросы - глобальная реализация запроса/ответа

Radio использует эти две конструкции и добавляет реализацию канала — предоставляя пространства имён для событий и запросов. Короче говоря, Radio — это глобальная, именованная система передачи сообщений, предназначенная для того, чтобы два по-иному не связанных объекта могли общаться и обмениваться информацией.

Индекс документации

  • Концепции Radio
    • Канал
    • Событие
      • Когда использовать События
    • Запрос
      • Возвращение значений из ответа
      • Когда использовать Запросы
  • Интеграция с Marionette
    • API
    • Примеры
      • Прослушивание событий на объектах
      • Ответ на запросы на объектах
      • События и запросы в одном объекте

Концепции Radio

Система Radio передачи сообщений раскрывает некоторые основные концепции:

  • Channel - механизм именования.
  • Event - оповещает другие части вашего приложения о том, что произошло что-то важное.
  • Request - выполняет отдельные функции в другой части вашего приложения.

Канал

channel является основной причиной использования Radio в качестве нашего агрегатора событий — он предоставляет чистую точку для разделения глобальных событий. Для получения канала используйте Radio.channel(channelName):

var Radio = require('backbone.radio');

var myChannel = Radio.channel('basic');

myChannel.on('some:event', function() {
  // ...
});

Канал доступен везде в вашем приложении. Просто импортируйте Radio и вызовите channel(), чтобы добавить обработчики, вызвать обратные вызовы или отправить запросы.

var Radio = require('backbone.radio');

var someChannel = Radio.channel('basic');  // Exactly the same channel as above

someChannel.trigger('some:event');  // Will fire the function call above

Пример

Событие

Radio Event работает точно так же, как и обычные события Backbone Events (типа модель/коллекция). На самом деле, он использует Backbone.Events миксин внутри, раскрывая его API:

  • channel.on('event', callback, [context]) - при запуске event вызывается callback
  • channel.once('event', callback, [context]) - то же, что и on, но запускается только один раз
  • channel.off('event') - прекращает прослушивание события
  • channel.trigger('event', ..args) - запускает event и передает аргументы в результирующий callback

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

Так как Radio можно импортировать в любом месте, мы можем использовать его как глобальный агрегатор событий:

var Radio = require('backbone.radio');

var myChannel = Radio.channel('star');

myChannel.on('left:building', function(person) {
  console.log(person.get('name') + ' has left the building!');
});

var elvis = new Bb.Model({name: 'Elvis'});
myChannel.trigger('left:building', elvis);

myChannel.off('left:building');

Как и Backbone Events, Radio поддерживает listenTo обработчик:

var Mn = require('backbone.marionette');
var Radio = require('backbone.radio');

var starChannel = Radio.channel('star');

var Star = Mn.Object.extend({

  initialize: function() {
    this.listenTo(starChannel, 'left:building', this.leftBuilding);
    this.listenTo(starChannel, 'enter:building', function(person) {
       console.log(person.get('name') + ' has entered the building!');
    });
  },

  leftBuilding: function(person) {
    console.log(person.get('name') + ' has left the building!');
  }
});

Обратите внимание, что обработчик событий может быть определён как метод (как в случае с событием 'left:building') или в строчном виде (как в случае с событием 'enter:building').

Пример

Как и в Backbone, обработчик событий вызывается с this, связанным с экземпляром Star. Полный список методов обработки событий см. в документации Backbone .

Когда использовать События

Событие — это просто уведомление о том, что что-то произошло, и вы можете или не хотите, чтобы другие объекты в вашем приложении реагировали на это. Вот несколько ключевых принципов, которые следует учитывать:

  • Если вы не знаете, что может отреагировать на событие, или вам всё равно, используйте Event
  • Если вы обнаруживаете, что называете это действием, которое произошло, используйте Event
  • Если для многих объектов приемлемо выполнить действие, используйте Event
  • Если вас не беспокоит, что никакие объекты не отреагируют, используйте Event

Если ваш случай использования не описан здесь, подумайте, хотите ли вы использовать запрос вместо этого.

Запрос

API запросов предоставляет унифицированный способ взаимодействия между несвязанными частями системы. Например, для отображения уведомлений в ответ на системную активность. Чтобы добавить обработчик к каналу запросов, используйте reply или replyOnce для добавления обработчика, который отсоединяется сразу после одного вызова.

Как и в случае с запросом, любые аргументы, переданные в channel.request , будут переданы в обратный вызов.

var Mn = require('backbone.marionette');
var Radio = require('backbone.radio');

var channel = Radio.channel('notify');

var Notification = Mn.Object.extend({

  initialize: function() {
    channel.reply('show:success', this.showSuccessMessage);
    channel.reply('show:error', function(msg) {
       // ...
    });
  },

  showSuccessMessage: function(msg) {
    // ...
  }
});

Например, при неудачной синхронизации модели:

var Mn = require('backbone.marionette');
var Radio = require('backbone.radio');

var channel = Radio.channel('notify');

var ModelView = Mn.View.extend({
  modelEvents: {
    error: 'showErrorMessage'
  },

  showErrorMessage: function() {
    channel.request('show:error', 'An error occurred contacting the server');
  }
});

Пример

Теперь, когда модель, привязанная к этому представлению, не может синхронизироваться с сервером, мы можем отобразить сообщение об ошибке пользователю.

Возвращение значений из ответа

API запросов также может возвращать значения, что делает его очень полезным для доступа к объектам, к которым иначе было бы сложно получить доступ. Например, предположим, что мы привязываем текущего авторизованного пользователя к объекту Application и хотим узнать, всё ли с ним в порядке.

var Mn = require('backbone.marionette');
var Radio = require('backbone.radio');

var channel = Radio.channel('user');

var App = Mn.Application.extend({
  initialize: function() {
    channel.reply('user:logged:in', this.isLoggedIn);
  },

  isLoggedIn: function() {
    return this.model.getLoggedIn();
  }
});

Затем, из другого представления, вместо того, чтобы пытаться найти модель User, мы просто request её:

var Radio = require('backbone.radio');

var channel = Radio.channel('user');

var loggedIn = channel.request('user:logged:in');  // App.model.getLoggedIn()

Пример

Когда использовать Запросы

Запрос, как вы, вероятно, догадались, — это запрос информации или выполнения действия. Вы, вероятно, захотите использовать запросы, когда:

  • Вы называете запрос действием, которое нужно выполнить, например, show:notification
  • Вы хотите получить возвращаемое значение запроса
  • Вы хотите вызвать ровно одну функцию

В дополнение к этой документации, документацию Radio можно найти на Github.

Интеграция с Marionette

Класс Marionette.Object предоставляет привязки для автоматического добавления обработчиков событий и/или ответов на запросы к вашим экземплярам объектов. Это работает с привязанным channelName для предоставления обработчиков с помощью свойств radioEvents и radioRequets. Любой класс, унаследованный от Mn.Object , имеет доступ к этому API.

API

  • channelName - определяет канал Radio, который будет использоваться для запросов и/или событий
  • getChannel() - возвращает экземпляр Radio.Channel, используя channelName
  • radioEvents - определяет хеш событий с событиями, которые нужно прослушивать, и соответствующими обработчиками
  • radioRequets - определяет хеш событий с запросами, на которые нужно отвечать, и соответствующими обработчиками

Примеры

Прослушивание событий в объекте

var Mn = require('backbone.marionette');

var Star = Mn.Object.extend({
  channelName: 'star',

  radioEvents: {
    'left:building': 'leftBuilding'
  },

  leftBuilding: function(person) {
    console.log(person.get('name') + ' has left the building!');
  }
});

Пример

Это даёт нам чёткое определение того, как этот объект взаимодействует с каналом радио star.

Ответ на запросы в объекте

var Mn = require('backbone.marionette');

var Notification = Mn.Object.extend({
  channelName: 'notify',

  radioRequests: {
    'show:success': 'showSuccessMessage',
    'show:error': 'showErrorMessage'
  },

  showSuccessMessage: function(msg) {
    // ...
  },

  showErrorMessage: function(msg) {
    // ...
  }
});

Пример

Теперь у нас есть чёткий API для взаимодействия с Notification по всему приложению. Не забудьте определить channelName в вашем определении Object.

Как и в обычном запросе/ответе, мы можем возвращать значения из этих привязанных обработчиков:

var Mn = require('backbone.marionette');

var App = Mn.Application.extend({
  channelName: 'user',

  radioRequests: {
    'user:logged:in': 'isLoggedIn'
  },

  isLoggedIn: function() {
    return this.model.getLoggedIn();
  }
});

Пример

События и запросы в одном объекте

var Mn = require('backbone.marionette');

var NotificationHandler = Mn.Object.extend({
  channelName: 'notify',

  radioRequests: {
    'show:success': 'showSuccessMessage',
    'show:error': 'showErrorMessage'
  },

  radioEvents: {
    'user:logged:in': 'showProfileButton',
    'user:logged:out': 'hideProfileButton'
  },

  showSuccessMessage: function(message) {
    // ...
  },

  showErrorMessage: function(message) {
    // ...
  },

  showProfileButton: function(user) {
    // ...
  },

  hideProfileButton: function(user) {
    // ...
  }
});

В несвязанном модуле:

var Radio = require('backbone.radio');
var User = require('./models/user');

var notifyChannel = Radio.channel('notify');
var userModel = new User();

// The following will call Notification.showErrorMessage(message)
notifyChannel.request('show:error', 'A generic error occurred!');

// The following will call Notification.showProfileButton(user)
notifyChannel.trigger('user:logged:in', userModel);

Пример

© 2017 Muted Solutions, LLC
Licensed under the MIT License.
https://marionettejs.com/docs/v3.5.1/backbone.radio.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API