hekevintran
hekevintran

Reputation: 23722

How can I run code any time part of an Ember view is rerendered?

My goal is to have a Facebook like button that can conditionally appear in an Ember view. My template is:

{{#if condition}}
    Click Like: <div class="fb-like fb_edge_widget_with_comment fb_iframe_widget" data-href="http://www.facebook.com/obnob" data-send="false" data-layout="button_count" data-width="100" data-show-faces="false"></div>
{{else}}
    Nothing to like here!
{{/if}}

If condition changes during the life of the page, the HTML code for the like button will be inserted and removed accordingly. The problem is that if the div of the like button is inserted after the page has loaded, the Facebook JavaScript library will not parse it and turn it into a like button. To do this you must call FB.XFBML.parse().

I tried using the didInsertElement() hook of Ember.View, but this runs only when the view is first inserted into the DOM, not after it is already there.

I tried to fix this by adding a script tag to the template:

<script>FB.XFBML.parse();</script>

This failed because the script tage interferes with Metamorph's script tags.

Questions

  1. Does Ember have a hook for running code anytime Metamorph changes an Ember view that has already been rendered?
  2. How do you write script tags in an Ember template without it clobbering Metamorph's tags?

Upvotes: 4

Views: 477

Answers (2)

s.ermakovich
s.ermakovich

Reputation: 2674

You can define a view for your button, and do any custom logic in the didInsertElement function. Example:

{{#if condition}}
    {{view App.LikeButton}}

...

App.LikeButton = Em.View.extend({
    templateName: 'like-button',
    didInsertElement: function() {
        //apply you custom logic here
    }
})

didInsertElement function will be called each time after view is rendered and added to the DOM.

Upvotes: 2

Ryan
Ryan

Reputation: 3594

You can observe variables inside your view. So you would do

App.View = Ember.View.extend({
    conditional: null,

    _conditionalChanged: function() {
        console.log('conditional changed');
    }.observes('conditional')
})

And this would allow you to fire code as your conditional changed.

That said, based on your original problem I do not think you should be using a conditional to manage state. You should look at using a StateManager inside your view. This way, as the state of your facebook button changes different actions/events can fire. In fact, you should have a totally separate view responsible for setting up the facebook button.

Upvotes: 2

Related Questions