Help test the preview release with new upcoming Blaze features (#each-in, #let, @index)

@nathan_muir oh, to be honest, I didn’t see it there after looking like a month ago. Not sure if it is new, or I just generally assumed the page didn’t change.

Are you able to foresee a release version/date for this?

I don’t have an opportunity to work on Blaze all the time, this is why the process is moving slow. Right now, we are in the feedback-collection phase, but so far not a lot of people have replied to this thread. cc @dgreensp

I see. Thanks.

Can you recommend things we should specifically test / look out for? Or are there any specific areas that you are expecting feedback on?

I am curious to see if this syntax actually makes the development easier
and less confusing as it doesn’t modify the data context but introduces a
variable. As a side effect, it is harder to access such new variable inside
helpers or event handlers. A possible solution is to introduce a JS lookup
interface, I didn’t think about it when we implemented these new
constructs. I am looking for things like this.

Oh. My 2¢:

  • I love the each in syntax. I find it much easier to read and follow. That may be because I am coming from a java world where official templating engines used that syntax. Anyway, I find it great and well worth the extra keystrokes while coding.
  • I am indiffirent to let. I could easily live with template helpers like I do know
  • @index is a quite good addition, but it can already be achieved in a number of unintrusive ways. So, nice to have, can live without.
  • The need for the extra with for getting the context in an event map… Well that kind of hurts. In fact, I’ve always found with confusing and a last resort kind of tool.

Yeah, ideally you shouldn’t have to use with to get what you want in the event handler. Would this be improved if you could lookup the variable from event handlers like this?

{{#each foo in foos}}
  <div class="clicky-div">{{foo.name}}</div>
{{/each}}
Template.name.events({
  'click .clicky-div': function (e) {
    console.log(this.lookup('foo').name);
  }
});
  • I find the each in syntax better than the original each.
  • let is not very useful to me, as I try to avoid modifying contexts. I rather use with (even with repeated arguments), to set the context more clearly.
  • Regarding getting the context in helpers and event handlers, I can live with with, as it allows seeing clearly what is going on.
  • I am not very fond of your lookup function, because I don’t know where it will look into. I need a scope. Why not having each in setting the context just like the original each did?

Each-in does fail on links created either with #linkTo or pathFor Syntax combined with iron-router.

Example:

<ul>
  {{#each person in people}}
    <li>
       {{#linkTo route='peopleView'}}
         {{person.name}}
       {{/linkTo}}
    </li>
  {{/each}}
</ul>

Besides that i like the new syntax a lot. It’s much cleaner, easier to understand and intuitive to use. Actually it is a kind of what i tried when i used #each the very first time.

I am not familiar with the way #linkTo works in Iron Router. Note that the new #each works very differently, it doesn’t set the data context, which might be what Iron Router expects to see.

The main point of the new #each, it actually does introduce the scope. The old #each was operating only in terms of data context (which is inherited when you call another template).

The lookup function would be the way to look up the Blaze Template scope.

It would have been great if the lookup were to be implicit as in
this.foo.name but I guess a dictionary lookup in that form would
still serve the purpose just fine.

The lookup function would be the way to look up the Blaze Template scope.

Can you please elaborate? What do you mean by “template scope”?

If the template scope includes parent scopes up to the root template, then this is not a scope at all.
This is how Blaze currently works: inside a template, if no argument is passed to a sub-template, then the sub-template context contains the parent template context. This “dump context” feature doesn’t look good to me.

If the template scope is always limited to the current template, then I like your idea very much. But then the “dump context” feature should be removed, otherwise there will be a coherence issue. Maybe defining a new template should be the only way to create a new context, and #with should be removed…

I like this idea because it is similar to how functions work in JavaScript - you define a new function to get a new scope. On the other hand, what about closures? It would be cumbersome if in JS you had to pass every single thing as an argument.

The scope is limited to the template, its environment where it was defined (and not where it was called). This is the first step on the way of moving away from the data context as the main way to pass variables around. In my mind, data context should be used as a model attached to views that is passed around implicitly, and scope variables (which are immutable with the current constructs of #let and #each in) are the way you compose templates with different arguments.

I think you should pass arguments along all the time explicitly if they are actually things you need to pass along. This is sort of separate from closures (unless you mean the concept of local functions). If there is something that you need to pass along every time and it is annoying, perhaps it should be part of your model and should be in the data context?

I meant in the case of closures. If templates were the only way to define scope, you couldn’t do things like closures in JS. Basically my point is that something like #let or #with is necessary.

Does this brings to the idea of merging the notions of “template data context” and “helper context”? What if, with the current Meteor version, I force myself to declare a new template each time I want a context?

Template.showAuthor.events({
  'click': function (event, template) {
    console.log('in local scope: ' + template.data.author.name);
    console.log('in closure scope: ' + template.closureData.editor.name);  // or a lookup function
  }
});
				{{#each author in authors}}
  {{>showAuthor author=author}}
				{{/each}}

<!-- Args: author -->
				<template name="showAuthor">
  <button class="clickMe">Click On {{author.name}}</button>
  <span>Editor: {{.../editor.name}}</span>     <!-- Three dots == closure data -->
</template>

It seems I can do all this already, right?

I am super excited for these features! Thanks Slava!

I have tried this for a few days and it is painful. The reason is that my unique context needs to be filled with both:

  • template parameters
  • values from template helpers

With the current Meteor version, if I want to only use currentData in helpers (no this), I have to create 2 templates:

<!-- Args: dateOfBirth -->
<template name="myTemplate">
  {{> myTemplate_createFinalContext dateOfBirth=dateOfBirth age=th_computeAge}}
	</template>

<!-- Args: dateOfBirth, age -->
				<template name="myTemplate_createFinalContext">
  ...
				</template>

What I would like is something like this:

<!-- Args: dateOfBirth -->
<template name="myTemplate" dateOfBirth=TEMPLATE_ARG age=th_computeAge>
  ...
</template>