What I love in Meteor is its easiness, isomorphic api (one way to do one thing). And having to remember 3 different way to access the same object depending of where I am, is definitely not easy nor isomorphic (ok we can troll about this term but you see what I mean).
Oh yes, I didnāt said it but the local reactive state is really a cool idea!
If Template.instance().state works everywhere, I donāt see why creating different way to do the same thing, itās disturbing for new people who try to learn
Template.instance() is the newest API for this, and the most consistent. Unfortunately, itās quite verbose, but we are working on some ways to make it more concise. (You can hack it into being more concise by setting Ti = Template.instance and calling it with Ti() )
Our favorite option right now is to make āthisā inside all template callbacks, events, and helpers be the template instance, and introduce a better way of calling the data context.
Good point. I think the more explicit, the better.
Another option could be passing template as argument to every callback function. But āthisā namespace also makes sense.
Very nice! I love that the new template state API can be something that people build on.
@dburles do you have any opinions on auto-migration of state across hot code push? I was going to just use an _id field in the template arguments/data context if one is present.
It would be amazing if itās possible to migrate without referencing an _id field and itās something I have been pondering, but havenāt really dug into. @sashko have you looked at anything beyond the _id field solution?
Well there needs to be some sort of unique string that identifies the template, otherwise you canāt match up the data before and after the migration. I think there needs to be a sane default that works most of the time, and then a good power user tool that lets you set a custom identifier. I was thinking using the _id of the data context as the default (another alternative would be using the path from the DOM or something), and then having an API for migrating manually.
In a lot of cases there wonāt be an _id available to reference, so some kind of identifier would be required, but Iām not sure exactly how we apply that state once the DOM is re-drawn.
Hello guys!
I known about template-scoped vars from here:
Loved the idea.
But Template.instance().state and template.state calls are so weird (they are not consistent in helpers and event handlers)! And it downed upon me to create ReactiveDict in data fn of Iron-router!!
We can do this:
data: ->
State: new ReactiveDict()
products: Products.find()
...
It seems so awesome to me!!! Jist had to share this to somebody. Registered here
Added: Found some bug. data function of router is reactive, so it reruns every change in any collection, it returns. So it flushes our State. Workaround is to add function
State: do ->
state = null
-> state ?= new ReactiveDict()
or in js:
State: (function() {
var state = null;
return function() {
return state != null ? state : state = new ReactiveDict();
};
})();
make āthisā inside all template callbacks, events, and helpers be the template instance
We just implemented small hack that exactly matches your last idea.
Template::methods = (methods) ->
helpers = {}
for name, method of methods
do (method) ->
helpers[name] = ->
tpl = Template.instance()
original = tpl.context # Save context if somebody already used it.
tpl.context = @
result = method.call tpl
tpl.context = original # Restore original context
return result
@helpers helpers
And now we write:
Template.myTemplate.onCreated ->
@myReactiveVar = new ReactiveVar ''
Template.myTemplate.methods
myVar: ->
@myReactiveVar.get()
# `this` coresponds to `Template.instance()`
fullName: ->
"#{@context.firstName} #{@context.lastName}"
# `this.context` coresponds to current data context.