Last active
March 2, 2016 23:26
-
-
Save SachaG/0bc20210c3e2c1e81600 to your computer and use it in GitHub Desktop.
Template Controller
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<template name="postsListController"> | |
{{> posts_list context}} | |
</template> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// see https://www.discovermeteor.com/blog/template-level-subscriptions/ | |
/* | |
This template acts as the controller that sets and manages the reactive context | |
for the embedded postsList template. It receives its parameters from a "caller" template. | |
*/ | |
Template.postsListController.onCreated(function () { | |
// 1. Initialization (*not* reactive!) | |
var instance = this; | |
// initialize the reactive variables | |
instance.terms = new ReactiveVar(instance.data.terms); | |
instance.postsLimit = new ReactiveVar(Settings.get('postsPerPage', 10)); | |
// 2. Autorun | |
// will re-run when terms are changed, either by the router or by the template itself | |
instance.autorun(function () { | |
// get terms from data context | |
var terms = Template.currentData().terms; // ⚡ reactive ⚡ | |
// get limit from local template variable | |
var postsLimit = instance.postsLimit.get(); // ⚡ reactive ⚡ | |
// create new subscriptionTerms object using the new limit | |
var subscriptionTerms = _.extend(_.clone(terms), {limit: postsLimit}); // extend terms with limit | |
// use this new object to subscribe | |
var postsSubscription = instance.subscribe('postsList', subscriptionTerms); | |
var usersSubscription = instance.subscribe('postsListUsers', subscriptionTerms); | |
var subscriptionsReady = instance.subscriptionsReady(); // ⚡ reactive ⚡ | |
console.log('// ------ autorun running ------ //'); | |
Tracker.onInvalidate(console.trace.bind(console)); | |
console.log("terms: ", terms); | |
console.log("limit: ", postsLimit); | |
console.log("ready: ", subscriptionsReady); | |
// if subscriptions are ready, set terms to subscriptionsTerms | |
if (subscriptionsReady) { | |
instance.terms.set(subscriptionTerms); | |
} | |
}); | |
}); | |
Template.postsListController.helpers({ | |
context: function () { | |
var instance = Template.instance(); | |
var terms = instance.terms.get(); // ⚡ reactive ⚡ | |
var postsReady = instance.subscriptionsReady(); // ⚡ reactive ⚡ | |
var postsLimit = terms.limit; | |
var parameters = Posts.getSubParams(terms); | |
var postsCursor = Posts.find(parameters.find, parameters.options); | |
var context = { | |
// posts cursor | |
postsCursor: postsCursor, | |
// posts subscription readiness, used to show spinner | |
postsReady: postsReady, | |
// whether to show the load more button or not | |
hasMorePosts: postsCursor.count() >= postsLimit, | |
// what to do when user clicks "load more" | |
loadMoreHandler: function (instance) { | |
event.preventDefault(); | |
// increase limit by 5 and update it | |
var limit = instance.postsLimit.get(); | |
limit += Settings.get('postsPerPage', 10); | |
instance.postsLimit.set(limit); | |
}, | |
// the current instance | |
controllerInstance: instance | |
}; | |
return context; | |
} | |
}); |
I switched back to the autorun pattern after all. Using Template.currentData()
still lets us depend on the parent context though.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
The advantages of the new pattern over the old one is that the new one is entirely driven by the data context it receives.
So the
context
helper will reactively update whenever the data context of the template changes. Whereas with the previous pattern, only the internal template instance reactive variables were reactive.By bringing everything into a single helper, we can also get rid of a few of the variables and simplify the code.
The downside is that since it contains 3 reactive variables the helper might end up re-running reactively 3 or 4 times as each variable changes. Ideally, the
posts_list
template that's called downstream would be smart enough to not re-render if the data context it's being passed due tocontext
re-running is identical to the previous one. But I'm not sure if that's the case?Also note that the code could be further simplified by using Percolate's find-from-publication package to restrict the
Posts.find()
topostsSubscription
. This would let us get rid of the two-stepsubscriptionTerms
hack.