Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow subscription to just a *param* in the hash changing #16

Open
cowboy opened this issue Aug 24, 2010 · 9 comments
Open

Allow subscription to just a *param* in the hash changing #16

cowboy opened this issue Aug 24, 2010 · 9 comments

Comments

@cowboy
Copy link
Owner

cowboy commented Aug 24, 2010

Justin's idea http://twitter.com/justinbmeyer/status/22037575805 and very cool.

@jupiterjs
Copy link

Yeah, I am no longer satisfied with JavaScriptMVC's approach to history, so I want to make bbq part of how history is used. I really like sammy's routing:

get('#/by_name/:name', function() {
alert(this.params['name']);
});

BUT!!!!

I think this would be even better if this was natural as listening to an event. I'd have to check if jQuery setup / init can do this, but:

$(window).bind("hashchange.bbq1", function(ev, params){

})

would be frankly disgustingly sick

@cowboy
Copy link
Owner Author

cowboy commented Aug 25, 2010

The API should be as jQuery-like as possible (and as BBQ-like as possible), so I'm thinking something like:

$(window).bind( 'hashchange', { param: 'a' }, function(event){
  // Only fires when fragment 'a' param changes

  var param = event.getParam(), // 'a' (NEW)
    param_val = event.getState( param ), // just like BBQ now
    param_val_coerced = event.getState( param, true ); // just like BBQ now
});

And this:

$(window).bind( 'hashchange', { params: [ 'a', 'b', 'c' ] }, function(event){
  // Only fires when any of fragment 'a', 'b' or 'c' param changes

  var param = event.getParam(), // 'a' or 'b' or 'c', depending (NEW)
    param_val = event.getState( param ), // just like BBQ now
    param_val_coerced = event.getState( param, true ); // just like BBQ now
});

In the latter, I think the handler should execute once for each param, so if both 'a' and 'b' change in a single hashchange event, the event handler will fire twice. Make sense?

I'm totally open to ideas. I'd really like to nail this out of the gate, though.

@cowboy
Copy link
Owner Author

cowboy commented Aug 25, 2010

Another idea that Paul Irish likes that's worth noting:

$(window).bind( 'hashchange', { param: 'a', value: 'x' }, function(event){
  // Only fires when the fragment changes, as long as the 'a' param
  // has a value of 'x'

  var param = event.getParam(), // 'a' (NEW)
    param_val = event.getState( param ); // 'x'

  // Do something with other, related, params.
});

This could be used to simulate routes (also, value could be a RegExp).

@jupiterjs
Copy link

Ah, I was thinking about that yesterday too. I was also thinking about 'fancy' routes.

"#/:a/options"

I'm not sure how that would work.

Also, what do you think about the event getting back a second argument which is params?

I suppose you don't always want to calculate it.

@cowboy
Copy link
Owner Author

cowboy commented Aug 25, 2010

I wouldn't add additional arguments to the callback, but instead add properties or methods to the already-passed event object. The param could be event.getParam() or event.param, whatever makes the most sense.

Enabling full-on routes could be handled by a more route-centric addon on top of BBQ, I don't think it should be in the core (at least, not for now).

@jupiterjs
Copy link

I always feel a little dirty adding expandos to events, even if they are jQuery.Event.

@josephtate
Copy link

I'm ok if you have an option to do routes style dispatching via an addon, however for large scale projects, object based dispatching works so much better. (I work on a project who's routes based dispatching builds a regexp 16KB long. Yuck.)

@cowboy
Copy link
Owner Author

cowboy commented Sep 2, 2010

Ok, what about this API idea?

var data;

data = 'a';         // triggered when param 'a' changes.
data = /.*/;        // triggered when hash (sans #) matches regexp.
data = { a: 'x' };  // triggered when param 'a' value == 'x'.
data = { a: /.*/ }; // triggered when param 'a' value matches regexp.

// Only if feasible (Q: handler gets triggered once for each match?)
data = [ 'a', 'b', 'c' ];           // triggered when either param 'a', 'b' or 'c' changes.
data = { a: 'x', b: 'y', c: /.*/ }; // does what you'd expect it to do.

$(window).bind( 'hashchange', data, function(event){

  event.data    // the data value passed in when binding.
  event.param   // the param that matched ( 'a' or 'b' or 'c' ).
  event.matches // if a regexp was used, this contains the result of the match.

  event.getState( event.param )       // the matching param's value.
  event.getState( event.param, true ) // the matching param's value (type coerced).
});

@josephtate
Copy link

For the data=['a', 'b', 'c'] and data={ a: 'x', b: 'y', c: /./ } cases, I would want a single event fired on a match of all params, and not once per each parameter that matches. For example, if I had a tab widget inside an accordion, I would want to set var 'a' for the state of the accordion, and var 'b' for the state of the tab. I'd use a data = {a: 'tabpage', b: /./} to subscribe to the hashchange event. Then if the accordion is on a page that the tab widget is not displayed on, then it doesn't get the event, but if if the accordion displays the "tabpage", any change in 'b' will trigger the event, but only once. It'd be a way to filter the events that are relevant.

All of that said, I'm having a hard time figuring out how that would work with JavascriptMVC where hashchange events are currently translated into a OpenAJAX hub event. This, I guess, is why Justin was pushing for a regex based routes system that uses a data type (string) that can be used directly as an OpenAJAX event name. However, I can imagine a scenario where you have thousands of regexes being run on every hash change, and worry about performance. Maybe jQuery/JSMVC event dispatching is somehow smarter than that, I don't know much about it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants