Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

access to contentIndex while iterating using #each #523

Closed
Gubbi opened this issue Feb 22, 2012 · 7 comments
Closed

access to contentIndex while iterating using #each #523

Gubbi opened this issue Feb 22, 2012 · 7 comments

Comments

@Gubbi
Copy link

Gubbi commented Feb 22, 2012

Hi, filing this bug as per comment made to this SO question: http://stackoverflow.com/questions/8870785/positional-index-in-ember-js-collections-iteration

It would be helpful to have access to contentIndex in #each.

@wycats
Copy link
Member

wycats commented Feb 25, 2012

My main concern about contentIndex is that it means that if you have something like:

{{#each}}
  {{contentIndex}}: {{name}}
{{/each}}

And then add something to the top of the list, it will require updating the contentIndex on every single view. It would be even more problematic if someone tried to do something clever with contentIndex (like conditional rendering), which could cause inserting an element at the top to become surprisingly massively expensive.

@busyloop
Copy link

busyloop commented Apr 4, 2012

I'll chime in here as I also find myself needing the pattern described in the SO-post quite often, along with something like this in the view:

# figure out previous element 
idx = this.getPath('_parentView.contentIndex')
prev = this.getPath('_parentView._parentView').get('content').objectAtContent(idx-1)

Unless there's a less convoluted way to write it with current Ember (I arrived there mostly by trial & error) then I would say this case deserves some sugar coating. The current way was far from intuitive for me, especially with the dedicated nested Metamorph that I'm still not quite sure why it's needed.

I've seen arguments for a presenter pattern and similar. But it all seems a little overkill when all I want is to express is something to the tune of:

{{#if previous.name == current.name}}
   version A
{{else}}
   version B
{{/if}

I see your performance-concern about contentIndex, though. Perhaps we could start out with "prev|first|lastElement", "first?" and "last?"? Those should be relatively cheap (I think) and would already cover many cases where CSS doesn't cut it.

@rlivsey
Copy link
Contributor

rlivsey commented May 11, 2012

As @wycats mentioned, contentIndex doesn't update so you can only use it for appending, not prepending. Instead I'm using the following:

previousMessageView: (() ->
  collection = @getPath("collectionView._childViews")
  index      = collection.indexOf(this)
  return false if index == 0
  collection[index-1]
).property()

Other properties then depend on this and I manually expire them on didInsertElement by checking where in the list the new items is inserted and seeing if it needs to update its neighbours:

checkNeighbours: () ->
  if prev = @get("previousMessageView")
    oldNext = prev.cacheFor("nextMessage")

    if this.get("content") != oldNext
      prev.beginPropertyChanges()
      prev.notifyPropertyChange("nextMessage")
      prev.notifyPropertyChange("nextMessageView")
      prev.endPropertyChanges()

  if next = @get("nextMessageView")
    oldPrevious = next.cacheFor("previousMessage")

    if this.get("content") != oldPrevious
      next.beginPropertyChanges()
      next.notifyPropertyChange("previousMessage")
      next.notifyPropertyChange("previousMessageView")
      next.endPropertyChanges()

Here's the full listing of where I took the above code from: https://gist.github.com/2659816

This seems to be reasonably fast, you obviously don't want all properties to update if the array length changes as it just gets slower and slower.

Having something like the above baked in would be rather useful.

@wagenet
Copy link
Member

wagenet commented Jul 13, 2012

I think @wycats was working on adding support for something like this, but I may be remembering incorrectly.

@machty
Copy link
Contributor

machty commented Feb 2, 2013

Trying to assemble a list of pending issues with #each... is this still a problem?

@Emerson
Copy link

Emerson commented Apr 18, 2013

Running into this issue myself with Ember RC2.

It's entirely possible I'm just missing something basic, but I can't find any reference to this in the docs.

@stefanpenner
Copy link
Member

I believe the position in set, doesn't feel like a rendering layer responsibility. I think this could be used only in very simple situations. The correct course of action is likely to have ordering information at the controller and item controller level, as sorting filter pagination could be taken into account.

rwjblue added a commit that referenced this issue Sep 3, 2019
Implement RFC #523 (@model argument for route templates and {{mount}})
sandstrom pushed a commit to sandstrom/ember.js that referenced this issue Jun 17, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants