strange errors in template:

633 views
Skip to first unread message

Andrew Dalke

unread,
Feb 2, 2011, 1:19:16 PM2/2/11
to KnockoutJS
I can't figure out why my code doesn't work. The full code is at the
end. The part I can't figure out is here:



<P data-bind="click: function(){item('I work')}">I work</P>

<div id="item_display" data-bind="template: {name: 'item-display-
tmpl', foreach: input}"></div>

<script id="item-display-tmpl" type="text/html">
<!-- change the 'P' to a 'button' and get "missing ) after argument
list" -->
<P data-bind="click: function(){item('${name}')}">${name}</P>
</script>
<!-- move the following commented line into the script and there's an
error -->
<!--<button data-bind="click: function(){item(${id})}">${name}</
button>-->


In short, I want lines which look like:
<P>Andrew</P>
<P>Dalke</P>
and when I click on the paragraph I get the text (or the id) shown
elsewhere.

The problem is the <P> data-bind works outside of the template but not
in the template. That is, I can click on the "I work" and see it, but
I can't click on the generated "Andrew" to see it.

I'm missing something in my understanding because if I change

<P data-bind="click: function(){item('${name}')}">${name}</P>
-to-
<button data-bind="click: function(){item('${name}')}">${name}</
button>
(or <a>) then I get the error message from Firefox 3.6.11:

missing ) after argument list

And if I replace that line with the HTML comment

<!--<button data-bind="click: function(){item(${id})}">${name}</
button>-->

then I get the error message "invalid property id".


Can I use bindings in a template? What am I doing wrong?

Best regards,
Andrew Dalke
da...@dalkescientific.com

P.S.
Here's my full page as a reproducible


<html>
<head>
<script src="jquery-1.4.4.min.js"></script>
<script src="jquery.tmpl.min.js"></script>
<script src="knockout-1.1.2.js"></script>

</head>
<body>

<P data-bind="click: function(){item('I work')}">I work</P>

<div id="item_display" data-bind="template: {name: 'item-display-
tmpl', foreach: input}"></div>

<script id="item-display-tmpl" type="text/html">
<!-- change the 'P' to a 'button' and get "missing ) after argument
list" -->
<P data-bind="click: function(){item('${name}')}">${name}</P>
</script>
<!-- move the following commented line into the script and there's an
error -->
<!--<button data-bind="click: function(){item(${id})}">${name}</
button>-->

<P>I see: <span data-bind="text: item"></span></P>

<script>
$(function() {

var data = [ {id: "id1", name: "Andrew"},
{id: "id2", name: "Peter"},
];

var viewModel = {
input: ko.observableArray(data),
item: ko.observable()
};

ko.applyBindings(viewModel);

})

</script>

</body>
</html>

rpn

unread,
Feb 2, 2011, 2:31:46 PM2/2/11
to KnockoutJS
Here is a copy that works: http://jsfiddle.net/rniemeyer/TBzFw/

A couple things that I changed:
-when you use "item" for the click binding within your template, it is
trying to execute it off of the element of the "input" array that is
being looped on by the foreach and then at a global level
-I changed it to use viewModel.item, but also had to define viewModel
outside of the jquery ready function, so that it was accessible
globally
-When defining your function within the template you can use $data to
reference the current object that the template is using. So, your
click binding works using: data-bind="click: function()
{ viewModel.item($data.name) }"
-Be careful of trailing commas when defining arrays or objects (your
data array). It can cause issues in Internet Explorer.

Hope this helps.

Andrew Dalke

unread,
Feb 3, 2011, 3:38:05 AM2/3/11
to KnockoutJS
On Feb 2, 8:31 pm, rpn <rnieme...@gmail.com> wrote:
> A couple things that I changed:
> -when you use "item" for the click binding within your template, it is
> trying to execute it off of the element of the "input" array that is
> being looped on by the foreach and then at a global level

Ah-ha! I didn't even consider that possibility.

While I don't need the ability to click on text in a P, can
you explain why replacing <button> with <P> doesn't work
for the text in the template?

http://jsfiddle.net/pjVba/

> -Be careful of trailing commas when defining arrays or objects (your
> data array).  It can cause issues in Internet Explorer.

Absolutely. And I saw in the archive that you pointed this
out before. :) My Python habits bite me here, so I've learned
to JSLint before I test on IE.

rpn

unread,
Feb 3, 2011, 9:20:14 AM2/3/11
to KnockoutJS
Make your paragraph tags lower-case and it works (<p></p> instead of
<P></P>). I know in XHTML tag names are supposed to be lower-case,
but I am not sure exactly why it doesn't work with upper-case for your
test and I didn't dig into it any further for now.

Hope this helps.

Andrew Dalke

unread,
Feb 3, 2011, 10:25:08 AM2/3/11
to KnockoutJS
Crazy! I had no idea that was supposed to be XHTML.
I'll have to retrain all my old HTML <P> habits.

Thanks again!

Andrew
da...@dalkescientific.com

rpn

unread,
Feb 3, 2011, 11:39:10 AM2/3/11
to KnockoutJS
I didn't mean that it has to be XHTML, just that XHTML says it should
be lower-case and that seems to work.

Seems to only happen in templates based on the memoization regex:

var memoizeBindingAttributeSyntaxRegex = /(<[a-z]+\d*(\s+(?!data-bind=)
[a-z0-9]+(=(\"[^\"]*\"|\'[^\']*\'))?)*\s+)data-bind=(["'])([\s\S]*?)\5/
g;

When doing the replacement this would not match something like <P data-
bind="text: something"></P>

Seems to work by changing it to allow a-z,A-Z for the element name.
Not sure if this would be considered a bug or not.

Glad that your project is working!

Andrew Dalke

unread,
Feb 4, 2011, 4:27:16 AM2/4/11
to KnockoutJS
On Feb 3, 5:39 pm, rpn <rnieme...@gmail.com> wrote:
> Glad that your project is working!

It's working very well - I'm really enjoying knockout.js!

Andrew
da...@dalkescientific.com
Reply all
Reply to author
Forward
0 new messages