Skip to main content

Bug Tracker

Side navigation

#7706 closed bug (wontfix)

Opened December 06, 2010 05:35AM UTC

Closed December 06, 2010 06:34AM UTC

Last modified December 16, 2010 07:40PM UTC

jquery.tmpl appears to execute ${} content tag 4 times

Reported by: corydodt Owned by:
Priority: undecided Milestone: 1.6
Component: templates Version: 1.4.4
Keywords: Cc:
Blocked by: Blocking:
Description

Try adding this to a template:

${console.log("hello")?"":""}

(This logs to the console and discards the undefined return value.)

"hello" appears 4 times in the js console.

Observed in: Chromium 7 and Firefox 3.6 (firebug)

Observed in: Windows7 and Linux

Observed in: jquery.tmpl beta1

I will attach a test document that demonstrates this behavior.

Attachments (0)
Change History (8)

Changed December 06, 2010 05:42AM UTC by corydodt comment:1

Please note that ''any'' expression there will be executed 4 times. This is not limited to console.log(). You could use a global counter and x++ instead. The value of x will be 4 times as high as you expected.

Learning how to use jsfiddle now so I can post this attachment...

Changed December 06, 2010 05:58AM UTC by corydodt comment:2

Here we go: jsfiddle bug 7706 quadruple execution

Changed December 06, 2010 06:07AM UTC by danheberden comment:3

description: \ Try adding this to a template: \ \ \ {{{ \ ${console.log("hello")?"":""} \ }}} \ \ \ (This logs to the console and discards the undefined return value.) \ \ "hello" appears 4 times in the js console. \ \ Observed in: Chromium 7 and Firefox 3.6 (firebug) \ Observed in: Windows7 and Linux \ Observed in: jquery.tmpl beta1 \ \ I will attach a test document that demonstrates this behavior.Try adding this to a template: \ \ \ {{{ \ ${console.log("hello")?"":""} \ }}} \ \ \ (This logs to the console and discards the undefined return value.) \ \ "hello" appears 4 times in the js console. \ \ Observed in: Chromium 7 and Firefox 3.6 (firebug) \ Observed in: Windows7 and Linux \ Observed in: jquery.tmpl beta1 \ \ I will attach a test document that demonstrates this behavior.

Another template example that shows the variable not incrementing http://jsfiddle.net/danheberden/UpkCV/

Changed December 06, 2010 06:24AM UTC by corydodt comment:4

Cool. What do you make of the difference?

I have made another fiddle that combines the two. Function calls are treated one way, naked expressions are treated another: http://jsfiddle.net/corydodt/McA5L/

Changed December 06, 2010 06:34AM UTC by danheberden comment:5

resolution: → wontfix
status: newclosed

The issue is because the expression in your template are evaluated when the template is created. It, essentially, creates a new function that gets ran to build the html with provided vars. It would make sense, then, that expressions such as if/ternary statements, increment/decrement, etc would get executed along the way.

In the mindset of a template, and therefore, application architecture, things like ternaries and increment operators have no place in the template. There are provisions for conditionals and iteration ( {{if}}, {{each}} ), but past that:that kind of logic should be done outside of your template. (such as with the function i provided in my jsfiddle).

I hope this makes sense. I'm going to close this bug report as working around this would, in effect, not let the tmpl functions operate properly. If you dig in a find a bug/problem in the actual code that's causing this behavior then of course open it back up.

Thanks for digging into this - this kind of stuff helps us gather the necessary points to go over in the documentation as we build it :D

Changed December 06, 2010 10:57AM UTC by jitter comment:6

component: unfiledtemplates

Changed December 06, 2010 05:36PM UTC by corydodt comment:7

You make a legitimate argument that this shouldn't be in template syntax, and in the future I'll use something like <script>x++</script> for those rare cases where this is cleaner.

I don't entirely understand your explanation. I found this unexpected because the documentation says expression. It also seems like, from your explanation, it should be executing 2 times instead of 4. Also, it begs the question "Why is the naked expression run 4 times but the function expression runs once?" Is there a special case for function calls? AFAIK expressions are expressions.

There should be a bug open for the documentation, though: It currently says this:

${fieldNameOrExpression}
fieldNameOrExpression  The name of a field on the current data item,
or a JavaScript function or expression to be evaluated.

I would prefer to see that written as ${fieldNameOrFunctionCall} and eliminate the word "expression" entirely.

Changed December 16, 2010 07:40PM UTC by BorisMoore comment:8

There was an issue that functions were getting evaluated more than once, which has now been fixed. (Use the latest builds to check this).

That said, Dan is correct that functions used in the template rendering should be limited to functions without side-effects. Calling the function twice should be the same as calling it once. (Idempotent). It is not appropriate to depend on the template engine rendering semantics calling the function only once. For example if you call tmplItem.update() then you functions will get called again for just that template item, so iterators etc. will break...