问题
Is there a way to listen to all events of a namespace. So when I listen to an event like this:
app.vent.on('notification(:id)', function(type){console.lof(type)})
It will listen to all events likes this:
app.vent.trigger('notification:info')
app.vent.trigger('notification:error')
app.vent.trigger('notification:success')
回答1:
No. Backbone typically fires a general eventName
event, as well as eventName:specifier
event. An example of this is Model.change
, which allows you to listen to all changes, as well as changes to individual fields:
model.on('change', this.onAnyPropertyChanged);
model.on('change:name', this.onNamePropertyChanged);
Following this pattern in your code, you could trigger your events as follows:
app.vent.trigger('notification', 'info');
app.vent.trigger('notification:info');
And listen to the general event:
app.vent.on('notification', function(type){
console.log(type); //-> "info"
});
回答2:
As mentioned by in this answer it is not possible to listen events with wildcards. But as you can listen to all
this will work:
vent.on('all', function(evenName, options) {
var type = evenName.split(/notification:/)[1];
if (type) {
console.log(type, options);
}
});
回答3:
I have written this helper:
export default class EventsHelper {
static triggerNamespacedEvent(eventBus, event, args) {
event.split(':').reduce((previous, current) => {
eventBus.trigger(previous, current);
return `${previous}:${current}`;
});
eventBus.trigger(event, args);
}
}
To use this in your view you would do:
actionOne(argsOne){
EventsHelper.triggerNamespacedEvent(this, 'click:chart:one', argsOne);
}
actionTwo(argsTwo){
EventsHelper.triggerNamespacedEvent(this, 'click:chart:two', argsTwo);
}
To listen for these events you would do:
//Listen for all clicks
this.listenTo(view, 'click', (args) => {
console.log(`clicked something: ${args}`); //output: clicked something: chart
});
//Listen for all chart clicks
this.listenTo(view, 'click:chart', (args) => {
console.log(`clicked chart: ${args}`); //output: clicked chart: one
});
//Listen for fully qualified event
this.listenTo(view, 'click:chart:two', (args) => {
console.log(`clicked chart two: ${args}`); //output: clicked chart two: evtArgs
});
回答4:
Warning: Listening to event namespaces on custom events may not work any more. For example, this does not work:
@listenTo @app, 'session', -> console.log ".listenTo `session` triggered"
@listenTo @app, 'session:login_success', -> console.log ".listenTo `session:login_success` triggered"
@app.on 'session', -> console.log ".on `session` triggered"
@app.on 'session:login_success', -> console.log ".on `session:login_success` triggered"
If I trigger 'session:login_success' on the @app
, only the two specific events fire, not the namespace one.
Related github issue: https://github.com/documentcloud/backbone/issues/2558
来源:https://stackoverflow.com/questions/15295768/backbone-events-with-wildcards