Running a function AFTER a meteor template is updated
Asked Answered
H

2

7

I have a meteor template rendering some html that I need to perform a jquery function on. Right now, I've set up a dependency so that every time the data (a list of objects) tied to that template changes, the function runs. I'm not at all sure this is the best way to do what I'm trying to do, but it does run the function every time I add/delete/rearrange objects, so that's a start.

However, the function seems to be running before the template is re-rendered, so the previous set of blocks get jquery-fied, but any blocks I've just added on that action do not.

Is there a way to force a function to run AFTER a template is rendered/updated? Any help is much appreciated!

(similar question here -- Meteor reactive jquery -- but it doesn't have any answers)

Here are some maybe-relevant code bits:

Template.showPictures.rendered =
    Deps.autorun () ->
      album = Albums.findOne(Session.get("selectedAlbum"))

      if (album)
        pictures = album.orderedPictures()
        MyApp.loadJQuery()

Template.showPictures.helpers
  pics: ->
    MyApp.myDependency.depend()

    album = Albums.findOne(Session.get("selectedAlbum"))
    album.orderedPictures()

(Why is the autorun in my Template.rendered thing? Not sure. That seemed like an okay place to put it, but this is my first time really dealing with dependencies, so I could be totally off-base here. Any ideas whatsoever on what's going wrong would be excellent.)

Haste answered 19/2, 2015 at 19:35 Comment(0)
H
6

You can use Tracker.afterFlush for that (and Tracker is a new name for Deps):

Template.showPictures.rendered =
    Tracker.autorun () ->
      album = Albums.findOne(Session.get("selectedAlbum"))

      if (album)
        Tracker.afterFlush ->
            // This will get executed when (among other things)
            // the UI has been updated.
            pictures = album.orderedPictures()
            MyApp.loadJQuery()

However, the Meteor way is something more like this:

<template name="things">
    {{#each things}}
        {{> thing}}
    {{/each}}
</template>

<template name="thing">
    <!-- Show the thing here... -->
</template>
Template.things.helpers({
    things: function(){
        return Things.find()
    }
})

Template.thing.rendered = function(){
    // This get executed each time a new thing is rendered!
}
Hieratic answered 19/2, 2015 at 20:26 Comment(0)
H
0

I have found something that works, but it still seems kind of hacky...

What I've ended up doing is setting a timeout. So now, instead of the code above, I have:

Template.sitePreview.rendered = () ->
  Deps.autorun () ->
    album = Albums.findOne(Session.get("selectedAlbum"))

    if (album)
      pictures = album.orderedPictures()
      setTimeout MyApp.loadJQuery, 500

So far, that's been enough time for the template to render/update, so the JQuery runs on all the most recent data. Still hopeful for a more elegant solution, but this will do !

Haste answered 19/2, 2015 at 20:7 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.