События Marionette
Система событий Marionette предоставляет систему для обмена сообщениями между объектами единообразным способом. В Marionette это обычно включает в себя объекты (модели, коллекции и представления), которые вызывают события, на которые реагируют и действуют другие объекты (обычно представления).
Этот раздел в основном посвящен событиям представлений и семантике и методам реагирования на события.
В этом разделе не рассматриваются события моделей и коллекций. См. документацию по представлениям.
Индекс документации
Вызов и прослушивание событий
Традиционная система обработки событий в Backbone также поддерживается в Marionette. Однако Marionette предоставляет альтернативную систему событий, использующую метод triggerMethod на Marionette.Object. Ключевое отличие между ними заключается в том, что triggerMethod магическим образом вызывают обработчики событий с именами в представлениях. Этот раздел описывает, как работает triggerMethod, и как настраиваются обработчики для его обработки.
Представление triggerMethod
Метод triggerMethod вызывает событие с заданным именем в представлении — все обработчики событий тогда будут вызваны. Если обработчики отсутствуют, вызов все равно будет успешным. Все аргументы после первого будут переданы всем обработчикам событий.
var Mn = require('backbone.marionette');
var MyView = Mn.View.extend({
callMethod: function(myString) {
console.log(myString + ' was passed');
}
});
var myView = new MyView();
/* See Backbone.listenTo */
myView.on('something:happened', myView.callMethod, myView);
/* Calls callMethod('foo'); */
myView.triggerMethod('something:happened', 'foo');
Вызов triggerMethod происходит из миксина trigger-method, который также является частью Marionette.Object и его подклассов, таких как Marionette.Application. Эта документация также применима.
Прослушивание событий
Триггеры событий Marionette работают так же, как и обычные события Backbone — вы можете использовать view.on и view.listenTo для реагирования на события:
var Mn = require('backbone.marionette');
var MyView = Mn.View.extend({
initialize: function() {
this.on('event:happened', this.logCall);
},
logCall: function(myVal) {
console.log(myVal);
}
});
Вы также можете использовать listenTo как в Backbone:
var Mn = require('backbone.marionette');
var OtherView = Mn.View.extend({
initialize: function(someView) {
this.listenTo(someView, 'event:happened', this.logCall);
},
logCall: function(myVal) {
console.log(myVal);
}
});
var MyView = Mn.View.extend();
var myView = new MyView();
var otherView = new OtherView(myView);
Как и в Backbone, listenTo передаст объект, на котором он вызывается, как переменную контекста. Они ведут себя точно так же, как и в Backbone, поэтому использование object.on потребует от вас отключения всех обработчиков событий самостоятельно, чтобы предотвратить утечки памяти. Однако Marionette предоставляет дополнительные вспомогательные средства как часть жизненного цикла представления, которые связывают и отключают обработчики событий за вас. Это — основа onEvent Привязки.
onEvent Привязка
Основное различие между Backbone.trigger и View.triggerMethod заключается в том, что triggerMethod может вызывать специально названные события в прикрепленном представлении. Например, представление, которое было отображено, вызовет view.triggerMethod('render') и вызовет onRender, — предоставив удобный способ добавления поведения к вашим представлениям.
Определение того, какой метод вызовет событие, легко, мы опишем это на примере с использованием before:dom:refresh, хотя это также работает с любыми пользовательскими событиями, которые вы хотите вызвать:
- Разделите слова вокруг символов
:, — например,before,dom,refresh - Заглавьте первую букву каждого слова —
Before,Dom,Refresh - Добавьте ведущий
on—on,Before,Dom,Refresh - Объедините в один вызов —
onBeforeDomRefresh
Используя этот процесс, before:dom:refresh вызовет метод onBeforeDomRefresh. Давайте посмотрим, как это работает на примере пользовательского события:
var Mn = require('backbone.marionette');
var MyView = Mn.View.extend({
onMyEvent: function(myVal) {
console.log(myVal);
}
});
var myView = new MyView();
myView.triggerMethod('my:event', 'someValue'); // Logs 'someValue'
Как и прежде, все аргументы, переданные в triggerMethod, попадут в обработчик события. Этот метод гарантирует отсутствие неожиданных утечек памяти.
Представление events и triggers
Представления могут автоматически привязывать события DOM к методам и события представления с events и triggers соответственно:
var Mn = require('backbone.marionette');
var MyView = Mn.View.extend({
events: {
'click a': 'showModal'
},
triggers: {
'keyup input': 'data:entered'
},
showModal: function(event) {
console.log('Show the modal');
},
onDataEntered: function(view, event) {
console.log('Data was entered');
}
});
Для получения дополнительной информации, см. документацию по представлениям.
События дочерних представлений
View и CollectionView могут отслеживать и реагировать на события любых дочерних представлений. Любые события, сгенерированные в представлении, автоматически передаются их непосредственным родительским представлениям. Давайте рассмотрим быстрый пример:
var Mn = require('backbone.marionette');
var Item = Mn.View.extend({
tagName: 'li',
triggers: {
'click a': 'select:item'
}
});
var Collection = Mn.CollectionView.extend({
tagName: 'ul',
childViewEvents: {
'select:item': 'itemSelected'
},
itemSelected: function(childView) {
console.log('item selected: ' + childView.model.id);
}
});
Пузырение событий
События, сгенерированные в представлении, поднимаются к непосредственным родительским представлениям, вызывая любые методы событий с префиксом childview: (более подробно об этом чуть позже) и любые методы, привязанные к атрибуту childViewEvents. Это работает для встроенных событий, пользовательских событий, вызванных triggerMethod, и связанных событий с помощью triggers.
Примечание: Автоматическое пузырение событий можно отключить, задав childViewEventPrefix значение false.
При использовании неявных обработчиков событий используется префикс события childview:*, который должен быть включен в обработчик:
var Mn = require('backbone.marionette');
var MyView = Mn.View.extend({
triggers: {
click: 'click:view'
},
doSomething: function() {
this.triggerMethod('did:something', this);
}
});
var ParentView = Mn.View.extend({
regions: {
foo: '.foo-hook'
},
onRender: function() {
this.showChildView('foo', new MyView());
},
onChildviewClickView: function(childView) {
console.log('View clicked ' + childView);
},
onChildviewDidSomething: function(childView) {
console.log('Something was done to ' + childView);
}
})
Примечание: triggers автоматически передаст дочернее представление в качестве аргумента родительскому представлению, однако triggerMethod этого не сделает, поэтому обратите внимание, что в приведенном выше примере triggerMethod явно передает дочернее представление.
Использование CollectionView
Это работает точно так же для CollectionView и его childView:
var Mn = require('backbone.marionette');
var MyChild = Mn.View.extend({
triggers: {
click: 'click:child'
}
});
var MyList = Mn.CollectionView.extend({
onChildviewClickChild: function(childView) {
console.log('Childview ' + childView + ' was clicked');
}
});
Префикс события дочернего представления
Вы можете настроить префикс события для событий, которые передаются через представление. Для этого задайте атрибут childViewEventPrefix для представления или collectionview. Для получения дополнительной информации о префиксе childViewEventPrefix см. Пузырение событий.
Значение по умолчанию для childViewEventPrefix — childview. Установка этого свойства в false отключит автоматическое пузырение событий.
var Bb = require('backbone');
var Mn = require('backbone.marionette');
var myCollection = new Bb.Collection([{}]);
var CollectionView = Mn.CollectionView.extend({
childViewEventPrefix: 'some:prefix'
});
var collectionView = new CollectionView({
collection: myCollection
});
collectionView.on('some:prefix:render', function(){
// child view was rendered
});
collectionView.render();
childViewEventPrefix может быть указан в определении представления или в вызове функции конструктора для получения экземпляра представления.
Явные обработчики событий
Для вызова определенных функций при срабатывании триггеров событий используйте атрибут childViewEvents для сопоставления событий дочерних представлений с методами родительского представления. Это обрабатывает события, сгенерированные в дочерних представлениях — без префикса childview: — и вызывает указанный метод или присоединённую функцию.
var Mn = require('backbone.marionette');
var MyView = Mn.View.extend({
triggers: {
click: 'view:clicked'
}
});
var ParentView = Mn.View.extend({
regions: {
foo: '.foo-hook'
},
childViewEvents: {
'view:clicked': 'displayMessage'
},
onRender: function() {
this.showChildView('foo', new MyView());
},
displayMessage: function(childView) {
console.log('Displaying message for ' + childView);
}
});
Прикрепление функций
Атрибут childViewEvents также может непосредственно прикреплять функции для обработки событий:
var Mn = require('backbone.marionette');
var MyView = Mn.View.extend({
triggers: {
click: 'view:clicked'
}
});
var ParentView = Mn.View.extend({
regions: {
foo: '.foo-hook'
},
childViewEvents: {
'view:clicked': function(childView) {
console.log('Function called for ' + childView);
}
},
onRender: function() {
this.showChildView('foo', new MyView());
}
});
Использование CollectionView's childViewEvents
var Mn = require('backbone.marionette');
// childViewEvents can be specified as a hash...
var MyCollectionView = Mn.CollectionView.extend({
childViewEvents: {
// This callback will be called whenever a child is rendered or emits a `render` event
render: function() {
console.log('A child view has been rendered.');
}
}
});
Вызов событий на дочерних событиях
Хэш childViewTriggers или метод позволяет делегировать события дочерних представлений без ручного задания привязок. Значения хэша должны быть строкой события, которое нужно вызвать в родительском представлении.
childViewTriggers — это синтаксический сахар поверх childViewEvents так же, как Триггеры представлений triggers — это синтаксический сахар над Событиями представлений events.
// The child view fires a custom event, `show:message`
var ChildView = Marionette.View.extend({
// Events hash defines local event handlers that in turn may call `triggerMethod`.
events: {
'click .button': 'onClickButton'
},
triggers: {
'submit form': 'submit:form'
},
onClickButton: function () {
// Both `trigger` and `triggerMethod` events will be caught by parent.
this.trigger('show:message', 'foo');
this.triggerMethod('show:message', 'bar');
}
});
// The parent uses childViewEvents to catch the child view's custom event
var ParentView = Marionette.CollectionView.extend({
childView: ChildView,
childViewTriggers: {
'show:message': 'child:show:message',
'submit:form': 'child:submit:form'
},
onChildShowMessage: function (message) {
console.log('A child view fired show:message with ' + message);
},
onChildSubmitForm: function (childView) {
console.log('A child view fired submit:form');
}
});
var GrandParentView = Marionette.View.extend({
regions: {
list: '.list'
},
onRender: function() {
this.showChildView('list', new ParentView({
collection: this.collection
}));
},
childViewEvents: {
'child:show:message': 'showMessage'
},
showMessage: function(childView) {
console.log('A child (' + childView + ') fired an event');
}
});
Использование CollectionView's childViewTriggers
var Mn = require('backbone.marionette');
// The child view fires a custom event, `show:message`
var ChildView = Mn.View.extend({
// Events hash defines local event handlers that in turn may call `triggerMethod`.
events: {
'click .button': 'onClickButton'
},
// Triggers hash converts DOM events directly to view events catchable on the parent.
// Note that `triggers` automatically pass the first argument as the child view.
triggers: {
'submit form': 'submit:form'
},
onClickButton: function () {
// Both `trigger` and `triggerMethod` events will be caught by parent.
this.trigger('show:message', 'foo');
this.triggerMethod('show:message', 'bar');
}
});
// The parent uses childViewEvents to catch the child view's custom event
var ParentView = Mn.CollectionView.extend({
childView: ChildView,
childViewTriggers: {
'show:message': 'child:show:message',
'submit:form': 'child:submit:form'
},
onChildShowMessage: function (message) {
console.log('A child view fired show:message with ' + message);
},
onChildSubmitForm: function (childView) {
console.log('A child view fired submit:form');
}
});
События жизненного цикла
Представления Marionette вызывают события во время создания и уничтожения жизненного цикла. Для получения дополнительной информации см. документацию о View Жизненном цикле.
© 2017 Muted Solutions, LLC
Licensed under the MIT License.
https://marionettejs.com/docs/v3.5.1/events.html