1

I am trying to create hierarchical result with callbacks.

This is my function structure:

el('root', function(){
 el('users', function(){
 el('show');
 });
 el('products');
});

The result I want is:

assert.equal(result, [ 'root', 'root_users', 'root_users_show', 'root_products' ] );

I got pretty far in my implementation: http://jsfiddle.net/5ur5u/ The problem I have is that I am increasing my depth each time el is called. It works fine until it reaches products. Because show puts depth on 3 it means that products will be added at the end of show.

So if anybody can give me a hand or point me into the right direction that would be great.

asked Mar 11, 2012 at 13:59
2
  • This is tricky because el cannot (in a sane way) know in which level it was called. You might be better off passing a function el to the callback, which is different each time. Commented Mar 11, 2012 at 14:02
  • You mean el('root', function(el){ el('users' ) } );? Commented Mar 11, 2012 at 14:09

3 Answers 3

2

You're very close. You just need to decrement the depth at the end. See http://jsfiddle.net/Z2qsy/

Rather than

depth += 1;
fn();

Do this

depth += 1;
fn();
depth -= 1;
answered Mar 11, 2012 at 14:11

1 Comment

Think you forgot to click update in jsfiddler. Here's a link with a working example with your patch. jsfiddle.net/Z2qsy/1
1

This does what you are asking for

var names = [];
var result = [];
function el(name, f)
{
 names.push(name);
 result.push(names.join("_"));
 f && f();
 names.pop();
}
el("root", function(){
 el("users", function(){
 el("show")
 });
 el("products");
});
alert(result);
answered Mar 11, 2012 at 14:20

1 Comment

Bah, was so proud of what I had but this is a million times better.
1

(削除) Since el is the very same function each time it is called, there is no way to distinguish between it being called in one level (show) or another (products). You can increment the level each time el is called, but there is no way to know when to decrement it because there is not something like the "opposite" of calling in JavaScript. (削除ここまで)

A slightly better option is to pass a new function to the callback (you could give it the same name el), which is different so that each level has its own el function. That way, the result can be built correctly: http://jsfiddle.net/5ur5u/2/.

var result = [];
function el(name, fn) {
 result.push(name); // add current name
 if(fn) { // if there is a function
 fn(function(name2, fn2) { // call the function with a new function
 el(name + "_" + name2, fn2); // which calls `el` recursively
 // with the names combined
 });
 }
}
el('root', function(el) {
 // this `el` refers to the function passed as declared above,
 // which is not the same one as the initial `el`
 el('users', function(el) {
 el('show');
 });
 el('products');
});
answered Mar 11, 2012 at 14:10

1 Comment

+1 I like it how your solution simplifies the library code but makes the url map a little more verbose (the extra el parameter).

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.