1

I have an Ember app in which there's an Index view and on the same page (nested) there's a corresponding detail view. Let's say the resource we're dealing with is a Post - and a Post can have many Comments. On the index page there's a list of Posts - each one is clickable. When you click on a Post - the detail portion of the page loads with the Post's details - including a semantic-ui accordion for the Comments.

I've subclassed Ember.Component in order to create a semantic-accordion component and display an accordion with a Post's comments. In semantic-accordion's 'didInsertElement' method - I found it necessary to do the following in order to get the accordion to work ...

didInsertElement: ->
  @_super()
  Ember.run.scheduleOnce 'afterRender', this, ->
    @$().accordion()

This works great - except, and here's the rub - it only works after a page reload. If I click on a different Post - in order to view the details of that Post - the accordion for the newly clicked Post's comments does not work. I know why it doesn't work - because the 'didInsertElement' method didn't execute again as a result of the ajax-based 'detail' reload. I'm just not sure what to do to fix it. Hoping someone here knows.

Thanks

user554053
  • 83
  • 2
  • 9

2 Answers2

0

This is a common problem with jQuery plugins. The best solution I've found for that is to enclose that view in an {{#if}} that will cause a redraw every time you need it. The naive way is setting a shouldRefresh property through the ajax call - but that is a bit hack-ish. The better way is to {{#if}} on something that actually changes on the AJAX call, like an ID.

Meori Oransky
  • 688
  • 4
  • 8
0

Making components that wrap jQuery plugins can be a challenge, but usually I've found there is a way to work with a mature plugin API to get what you want.

For instance, I'm looking at the documentation for jQuery UI accordion plugin and I notice that there is a refresh method:

Process any headers and panels that were added or removed directly in the DOM and recompute the height of the accordion panels.

Pretending that you pass in your comments to the accordion component as content, I wonder if you could do something like this:

afterRender: (callback) ->
  Ember.run.scheduleOnce 'afterRender', this, callback

didInsertElement: ->
  @_super()
  @afterRender ->
    @().accordion()

contentDidChange: (->
  return unless @get('element')
  @afterRender ->
    @$().accordion("refresh")
).observes('content')

I'm not sure if refresh actually fixes the issue that you're seeing, but it's worth looking through the docs of your plugin to see if there is some way to fix the issue without reinitializing the whole plugin.

Mitch
  • 1,535
  • 13
  • 21