4

Obligatory jsFiddle example.

When I run an array of strings through jQuery's $.each function, I get what I expect.

$.each(["abc", "123", "def", "456"], function (i, val) {
    $("<li></li>").text("source[" + i + "]: " + val).appendTo(".eachResults");
    // run for each string in the array ("abc", "123", ...)
});

When I run the same array of strings through jQuery Template's {{each}} operator, though, it treats it as a two dimensional array of chars.

<script id="testTemplate" type="text/x-jquery-tmpl"> 
<ul>
    {{each(i, prop) $data}}
    {{if $data.hasOwnProperty(i)}}
    <li>
        source[${i}]: ${$data[i]}
        {{! run for each char of each string in array (0:"a", 1:"b", 2:"c", 0:"1", 1:"2", 3:"3", ...)}}
    </li>
    {{/if}}
    {{/each}}
</ul>
</script>

$("#testTemplate").tmpl(["abc", "123", "def", "456"]).appendTo(".tmplResults");

Since the i in the template always seems to reference correctly into $data, I don't really have any clue how this indexing works at all. It seems like i would need to be a two-dimensional index to work correctly, but it doesn't appear to be (typeof (i) === "number").

Follow-up question

@mblase75 certainly explained the issue here. Unfortunately, given this was a subset of my actual code, it turned out to just bring up a different question about recursively calling an {{each}} template when you come across an array of strings.

1 Answer 1

4

Remember that templates are an implicit loop. Your original {{each}} was looping through each character in each string -- the template was looping through each string in the array.

This will give you the desired result (more or less):

<script id="testTemplate" type="text/x-jquery-tmpl"> 
    <li>
        source[]: ${$data}
    </li>
</script>

http://jsfiddle.net/wuEyp/10/ uses the above code. The index is gone because the template doesn't seem to provide for it at the "root" level.

http://jsfiddle.net/wuEyp/11 will add the indexing back in using a function. For some reason, I can't do it properly with a closure.

Sign up to request clarification or add additional context in comments.

5 Comments

Remember that templates are an implicit loop. Your original {{each}} was looping through each character in each string -- the template was looping through each string in the array.
jsfiddle.net/wuEyp/11 will add the indexing back in. For some reason I can't do it properly with a closure....
I think your first comment is the actual answer to the question (still confirming). Just edit your own answer and put your comments in there and I will probably end up accepting it.
I'm definitely going to have to just call this question good and start a new one more specific than this. My problem is a recursive {{each}} template (basic JS reflection) that is going too deep on arrays of strings. I just need to figure out how to shortcut that recursion on such arrays. That's what I get for trying to cut out just enough to present the problem: an answer to the question but not my problem. :P
if you happen to have a way to avoid this implicit loop, there is a follow-up question out now.

Your Answer

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.