laravel / framework

The Laravel Framework.
https://laravel.com
MIT License
32.12k stars 10.87k forks source link

Events hook with wildcards * or namespaces would be awesome #1126

Closed rezen closed 11 years ago

rezen commented 11 years ago

Backbone.js has a nice event system http://backbonejs.org/#Events that allows you to hook into specific events or as well as hook into events that fall under a 'namespace'. This concept could be a nice addition to build into the current event system.

So for example if you fire an event under the 'view' event namespace, you could listen for both the specific event as well as any namespace events.

// event that fires
Event::fire('view.precompile');
//......

// listeners that can get triggered
Event::listen('view.*', function(){...})
// or if I only want the specific event
Event::listen('view.precompile', function(){...})

This concept may end up firing too many events, but could be useful for debugging.

yuripave commented 11 years ago

Taylor, this commit added event name to the end of payload array in order for wildcard events to identify the exact event name. But seems putting it at the beginning of the payload () then document it will be more consistent as if the data passed from fire() is not empty http://paste.laravel.com/q4Q. Maybe put the event name to payload using array_unshift instead []? What do you think?

taylorotwell commented 11 years ago

Thought about that but it's not needed for most listeners and would break existing apps.

On May 1, 2013, at 12:49 PM, yuripave notifications@github.com wrote:

Taylor, this commit added event name to the end of payload array in order for wildcard events to identify the exact event name. But seems putting it at the beginning of the payload () then document it will be more consistent as if the data passed from fire() is not empty http://paste.laravel.com/q4Q. Maybe put the event name to payload using array_unshift instead []? What do you think?

— Reply to this email directly or view it on GitHub.

yuripave commented 11 years ago

If this is final, then I will have to workaround in my solution, correct?

Event::listen('event', function($param1 = null, $param2 = null)
{
    if ($param1 == 'event') $param1 = null;
    // things to do depends on values of $param1 and $param2
});

Event::fire('event');
Event::fire('event', array('foo', 'bar'));
deefour commented 11 years ago

@taylorotwell The new setupWildcardListen is only going to add the wildcard listener if a more explicit listener the wildcard will fire on has previously been added.

For example, the below listener will not fire when calling ->save() on some model extending Eloquent ("wildcard" will not output).

Event::listen('eloquent.saving: *', function($model, $event) {
  echo "wildcard" . PHP_EOL;
});

However, if I first add a lister on SomeModel, later adding the wildcard listener will result in both "regular" and "wildcard" being output (both events fire properly).

Event::listen('eloquent.saving: SomeModel', function($model, $event) {
  echo "regular" . PHP_EOL;
});

Event::listen('eloquent.saving: *', function($model, $event) {
  echo "wildcard" . PHP_EOL;
});

In #957 you mentioned 89f3c2c allows for events like eloquent.*, but it seems the required existence of a more-explicit listener the wildcard would match against shouldn't be necessary.

taylorotwell commented 11 years ago

Whoops. I'll take a look at that.

taylorotwell commented 11 years ago

Fixed.

deefour commented 11 years ago

@taylorotwell Thank you :beers: