Good way to integrate query-layout with reactive templates + async data sources?

360 views Asked by At

I'm working on a Meteor app that gets data from Facebook & I would like to use jquery-layout for presentation. I suspected that there might be some "subtleties" when trying to use jquery to modify HTML in reactive templates, so I set up a relatively simple test case that goes something like this (paraphrased for brevity)...

<body>
{{> mainTemplate}}
</body>

<template name="mainTemplate">
  {{#with userInfo}}  
  {{> partialNorth}}  
  {{> partialWest}}  
  {{> partialCenter}}  
  {{> partialEast}}  
  {{/with}}  
  {{layItOut}}  
</template>  

Template.mainTemplate.userInfo returns contents of a Session variable that starts with a default value and asynchronously get updated with info from Facebook.

Template.mainTemplate.layItOut sets up a call to Meteor.defer with a callback fcn that actually executes the 5 lines of jquery-layout code.

And that seems to work pretty well...

  • the initial display is as expected/intended (although there's a brief period where the page is not laid out)

  • any updates to the reactive context cause re-execution of the layout (again, w/brief-but-visible re-layout)

So, why am I whining? Mostly I would like to find a cleaner approach that does away with the noticeable re-layout activity.

I could make the reactive contexts more granular, but I'm not sure that this would really help.

Alternatively, I suppose I could experiment with directly controlling rendering (e.g., via Meteor.ui.render() , but that sounds like a lot of work ;-)

I think what I'd really like is either

a) a way to hook into Meteor render events

or better still

b) a cleaner way to connect query-layout to templates

Thoughts?

1

There are 1 answers

0
mgleavitt On

So I managed to educate myself enough to answer my own question in case anyone else finds it useful. Bottom line is that I was wrong on several levels; making the reactive contexts more granular is the answer (or at least an answer).

In the example I gave, I made the whole page reactive by placing all of the rendering within the #each construct. What I now do is try to make the reactive contexts as small as possible so that only a (relatively) small part of the page is re-rendered on any reactive change and all of the reactive elements are contained below (or way below) the level of the jquery ui elements.

I.e., something like this:

<body>
{{> mainTemplate}}
</body>

<template name="mainTemplate">

{{#with userInfo}}

{{> partialNorth}} 
{{> partialWest}}  
  ... 

{{/with}}

  {{layItOut}}  
</template>  

<template name="partialNorth">
  <div class="ui-layout-north">  <-- definition for jquery-layout north panel
    <h1>This is the north pane</h1>
    <p>The user data go next:</p><br />
    {{> templateUserData}}
  </div>
</template>

<template name="templateUserData">
  <div>
    {{#with theUserData}}  <-- Assumes a helper function 'theUserData' for this template
      <p>First name: {{first_name}}</p>
      <p>Last name: {{last_name}}</p>
      ...
    {{/with}}
  </div>
</template>

Once you have the reactive elements below the jquery ui elements (I have tried it with panels, tabs, accordions, buttons and pop-ups so far) the whole thing works just like it said it would in the shiny brochure! ;-)