When I select the button at the bottom of my page to load more messages, the new messages get loaded at the bottom of the table, but the page reloads and I get taken to the top of the page no matter what JQuery I come up with. Now I have to scroll back down to the bottom of the page to see the new messages.
When I remove the {{#if Template.subscriptionsReady}}, as I would expect, the new messages get loaded at the bottom of the table and there’s no ‘jumping’ to the top of the page.
Any Ideas on the why it’s happening and how to avoid it (prefer to keep it around if possible)?
Hi, it is expected, because while new records are fetched from the server your DOM is shrinked to single loading.... The problem is your {{else}}. Just remove it. As for me - I do not use built in subscriptionsReady and manage all subscribtions by the hand.
That’s what I’ve been using here http://starport.meteor.com/academy/new Also have the load more button in an {{if hasMoreItems}} but the problem with that as you might see is that sometimes the load more button gets displayed a second before the items in {{each}} show on page. Could put it in a delay but it ain’t perfect.
Is there any kind of hook for just before the page gets shown to the user, when both subscriptions & the DOM are ready. Could really use it for example when you need to run a jquery function last second (like Isotope) when everything is truely ready. Instead of having to trigger them with a slight delay after subscriptions is ready like here http://starport.meteor.com/boardwalk Which just feels unreliable.
I don’t understand what your exact problem is, but here is an answer to this specific question (not tested):
Template.myTemplate.rendered = function() {
var self = this;
self.hasJustBeenRendered = true;
this.autorun(function() {
if (self.subscriptionsReady() && self.hasJustBeenRendered) {
// You get here when both the DOM and all subscriptions are ready
...
}
self.hasJustBeenRendered = false;
});
}
Just tried it out, didn’t work. self.hasJustBeenRendered gets set to false before the subscription is ready so everything within the if statement never runs. Your code would work if the entire Template.myTemplate.rendered would run again when the subscription is ready but it doesn’t.
Without the self.hasJustBeenRendered would look like this:
Template.myTemplate.onRendered = function() {
var self = this;
this.autorun(function() {
if (self.subscriptionsReady()) {
// > $Isotope function that changes the DOM & CSS
}
});
}
What’s supposed to happen:
Subscriptions are ready
Items from the subscription updates the DOM {{each}{{/each}} blocks
Isotope function updates the DOM to move the items in the {{each}{{/each}} blocks to their correct position and applies CSS
The user gets to see the template
What actually happens:
Subscriptions are ready
Isotope function updates the DOM to move the items in {{each}{{/each}} blocks in their correct position in the DOM and applies CSS
Items from the subscription updates the DOM {{each}{{/each}} blocks
The user gets to see the template
The user gets to see a mangled up page because the Isotope function ran before all the items were placed in the DOM. So Isotope missed all the items / ran too early.
Only way I’ve been able to solve it so far is put a delay on Isotope to allow for the items be placed in the DOM {{each}} blocks first.
My experiments suggest that the rendered (now onRendered) callback gets called when the outermost element of the template has been inserted into the DOM.
What I’ve managed to get working is to insert a dummy template at the end of the HTML and set up an onRendered callback for that. At least in my case (using the leaderboard example), all DOM elements have been inserted when that final onRendered callback is executed.
For your use case it should then be possible to use your jQuery selector in that final Template.foo.onRendered() callback.
if the value change all your DOM here would be replaced. Thats why you can see DOM messed (and scroll position is dropped) while new data are coming from the server
thats right. You can just try it. Pass {enter: function(), exit: function()} to handle subscribtion start fetching and ready. Also it doesnt drop current documents state until new data is comed