accessing $data in afterRender function call

2,660 views
Skip to first unread message

gaffe

unread,
Nov 30, 2011, 11:14:43 PM11/30/11
to KnockoutJS
Hi guys,
I am trying to do this:

<!-- ko foreach: {data: viewModel.Files(), afterRender: function() { //
I need to access $data.Id() in here } } -->

with $data being the current object in the Files() array, but $data
seems to point to some other kind of object.

Anyone know what $data is in that context and/or how I can access the
current object that pertains to the section that was just rendered?

Thanks,
Enis

Orson Sampson

unread,
Dec 1, 2011, 8:04:59 AM12/1/11
to knock...@googlegroups.com
I'm my case, the function attached to the "afterRender" doesn't get executed when used with the containerless control flow (<!-- -->).

Michael Best

unread,
Dec 1, 2011, 8:21:47 AM12/1/11
to KnockoutJS
I think this will work:

<!-- ko foreach: {data: viewModel.Files(), afterRender:

function(elems, data) { do something with data.id(); } } -->

-- Michael Best

Orson Sampson

unread,
Dec 1, 2011, 11:08:57 AM12/1/11
to knock...@googlegroups.com
Perfect! Thanks

hugh...@gmail.com

unread,
May 21, 2012, 1:27:29 AM5/21/12
to knock...@googlegroups.com
Good evening,
I'm having a problem in version 2.1.0 of Knockout Js with the ko foreach binding inside of containerless control flow syntax, when specifying afterRender, same setup as the OP.

Problem is, the afterRender is called for each item in the list.
I was hoping to have it called one time after the whole list has been processed.
I need to tell jQuery Mobile to re-render it's styles on the containing UL list which has a header item which is not KO bound.
I run into problems if I tell jQuery Mobile to re-render during the afterRender call currently specified in the ko foreach comment as the OP has it.
That is because if the list contains multiple items, I tell jQuery to style it in item 1's callback,
then Knockout tries to add item 2 and jQuery has modified the DOM.  Knockout gets lost because the DOM is not as expected.

Solution would be for the afterRender to only fire after the whole foreach is finished.
If I wanted it to callback during every iteration I could bind to the afterRender on one of my li elements inside the foreach.

Thanks!
H

hugh...@gmail.com

unread,
May 21, 2012, 1:45:08 AM5/21/12
to knock...@googlegroups.com
Hey I got it figured out.
See my Fiddle here:
I needed to add parentheses to my afterRender binding.

THIS IS CORRECT:
<!-- ko foreach: {data: getFiveItems(), afterRender: refreshListview()} --> 

THIS IS NOT CORRECT:
<!-- ko foreach: {data: getFiveItems, afterRender: refreshListview} --> 

Thanks!
Hugh

Michael Best

unread,
May 21, 2012, 4:32:42 PM5/21/12
to KnockoutJS
By specifying it as refreshListview(), the function gets called when
the binding is parsed, which is before foreach is run. Since your
function doesn't return anything, afterRender is just set to
undefined.

There is currently an open request to add a callback like you want:
https://github.com/SteveSanderson/knockout/pull/339

Another option is to use a custom binding: http://jsfiddle.net/mbest/439nV/10/

-- Michael
Reply all
Reply to author
Forward
0 new messages