Bug Tracker

Opened 9 years ago

Closed 9 years ago

Last modified 9 years ago

#7706 closed bug (wontfix)

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 (last modified by danheberden)

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.

Change History (8)

comment:1 Changed 9 years ago by corydodt

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...

comment:2 Changed 9 years ago by corydodt

Here we go: jsfiddle bug 7706 quadruple execution

comment:3 Changed 9 years ago by danheberden

Description: modified (diff)

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

comment:4 Changed 9 years ago by corydodt

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/

comment:5 Changed 9 years ago by danheberden

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

comment:6 Changed 9 years ago by jitter

Component: unfiledtemplates

comment:7 Changed 9 years ago by corydodt

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.

comment:8 Changed 9 years ago by BorisMoore

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...

Note: See TracTickets for help on using tickets.