Rendering a list of items breaks the order

63 views
Skip to first unread message

alexandroid

unread,
Feb 28, 2012, 1:21:22 AM2/28/12
to Sammy.js
Hi all,

I am trying to load a list of ordered items from the server and then
render them using my template (and http://sammyjs.org/docs/tutorials/json_store_1
for guidance):

questions_container = $('.questions_container').first()

@sammy = Sammy '#foo', ->
@use 'Template'

@get '#/', (context) ->
context.log 'Loading questions...'
@load('questions.json')
.then (items) ->
$.each items, (i, item) ->
context.log item.id
context.render('assets/question.template', {item: item})
.appendTo(questions_container)

I observe interesting effect that in the firebug console all items are
logged in the order returned by the server (ordered by id), however in
the DOM they tend to be mixed up.

Is this happening because of render() parallel logic? How can I make
sure that order of items is preserved in DOM?

Thank you,
Alex

PS: Apologies to those who already saw this question on stackoverflow
- http://stackoverflow.com/questions/9450817/rendering-a-list-of-items-breaks-the-order
I am just really stuck here...

Aaron Quint

unread,
Feb 28, 2012, 2:42:50 AM2/28/12
to sam...@googlegroups.com
When you use $.each and then fire off a new render, you can't
guarantee that the items fire in order since each render will happen
async.

What you really want is renderEach:
http://sammyjs.org/docs/api/0.7.1/all#Sammy.RenderContext-renderEach

The code is probably informative too:
https://github.com/quirkey/sammy/blob/v0.7.1/lib/sammy.js#L1665

You should search this list for it, as there are a number of good examples.

Hope that helps,
--AQ

> --
> You received this message because you are subscribed to the Google Groups "Sammy.js" group.
> To post to this group, send email to sam...@googlegroups.com.
> To unsubscribe from this group, send email to sammyjs+u...@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/sammyjs?hl=en.
>

alexandroid

unread,
Mar 3, 2012, 9:39:27 PM3/3/12
to Sammy.js
Hi Aaron,

Thanks! I actually saw renderEach but did not manage to make it work
at first attempt.

In my actual code I passed additional parameter to the template, in
addition to item, like this:

context.render('assets/question.template', {item: item,
max_num_answers: maxNumAnswers}).appendTo(questions_container)

...and a template would then use item.num_answers / max_num_answers to
calculate ratio value. With renderEach it turned out to be not so
straightforward.

If I understand correctly, I could use a callback to to string
replacements on HTML after each item's template render. But I could
not make it work (with empty no-op callback even), so instead I just
ended up modifying my list of items before passing to renderEach and
copying max_height to each of them manually:

@sammy = Sammy '#foo', ->
@use 'Template'
@get '#/', (context) ->
context.log 'Loading questions...'
@load('questions.json')
.then (items) ->
maxNumAnswers = Math.max.apply Math, ($.map items (item, i) ->
return.item.num_answers)
$.each items, (index, item) ->
item.max_answers = maxNumAnswers
context.renderEach('assets/question.template', 'item',
items).appendTo(questions_container)

This worked nicely. Thanks again!

~Alex Kamotsky

On Feb 27, 11:42 pm, Aaron Quint <aa...@quirkey.com> wrote:
> When you use $.each and then fire off a new render, you can't
> guarantee that the items fire in order since each render will happen
> async.
>
> What you really want isrenderEach:http://sammyjs.org/docs/api/0.7.1/all#Sammy.RenderContext-renderEach
>
> The code is probably informative too:https://github.com/quirkey/sammy/blob/v0.7.1/lib/sammy.js#L1665
>
> You should search this list for it, as there are a number of good examples.
>
> Hope that helps,
> --AQ
>
>
>
>
>
>
>
> On Mon, Feb 27, 2012 at 10:21 PM, alexandroid <kamot...@gmail.com> wrote:
> > Hi all,
>
> > I am trying to load a list of ordered items from the server and then
> > render them using my template (andhttp://sammyjs.org/docs/tutorials/json_store_1
> > for guidance):
>
> > questions_container = $('.questions_container').first()
>
> > @sammy = Sammy '#foo', ->
> >  @use 'Template'
>
> >  @get '#/', (context) ->
> >    context.log 'Loading questions...'
> >    @load('questions.json')
> >      .then (items) ->
> >        $.each items, (i, item) ->
> >          context.log item.id
> >          context.render('assets/question.template', {item: item})
> >            .appendTo(questions_container)
>
> > I observe interesting effect that in the firebug console all items are
> > logged in the order returned by the server (ordered by id), however in
> > the DOM they tend to be mixed up.
>
> > Is this happening because of render() parallel logic? How can I make
> > sure that order of items is preserved in DOM?
>
> > Thank you,
> > Alex
>
> > PS: Apologies to those who already saw this question on stackoverflow
> > -http://stackoverflow.com/questions/9450817/rendering-a-list-of-items-...
Reply all
Reply to author
Forward
0 new messages