How do I pass template variables in Meteor? - javascript

I couldnt find an answer for this but I've seen it before.
I want to render a template with a varable set from html and have access to it in js as well. Here's a simple example that covers both of these cases.
<template name="a">
{{>b param="hello"}}
</template>
<template name="b">
{{param}} {{param2}}
</template>
Template.b.param2 = function() {
if (this.param == "hello") {
return "world"
}
}
This doesnt seem to work though.
EDIT:
Well that all works apparently. I didnt include the #each:
<template name="a">
{{>b param="hello"}}
</template>
<template name="b">
{{#each something}}
{{param}}
{{/each}}
</template>
I think thats what's causing the problem. (sorry this example is a little contrived)

So this was king of a bad question but maybe it will save someone some trouble.
For the #each issue, the solution is to do {{../param}} which I found in another question.
However, this didnt work for me because I am using Autoform in which case I actually had to do {{../../param}}.

Related

Slots are not showing - Vue.js

I'm learning vue right now and have problems with understanding the slots.
I got two components:
BaseIcon
<template>
...
<slot name="test"></slot>
...
<template/>
EventCard
<template>
<router-link class="event-link" :to="{ name: 'event-show', params: {id: '1'}}">
..
<BaseIcon name="users" slot="test">{{ event.attendees.length }} attending</BaseIcon>
..
</router-link>
</template>
But the the "slot" ain't replaced with the content in the BaseIcon component tags in EventCard.
You could use it like v-slot because slot syntax is deprecated as mentioned here:
<BaseIcon name="users">
<template v-slot:test>
{{ event.attendees.length }} attending
</template>
</BaseIcon>
or a shorthand :
<BaseIcon name="users" >
<template #test>
{{ event.attendees.length }} attending
</template>
</BaseIcon>
I had a very similar problem recently. Turned out there was a tiny glitch in my HTML markup (I hadn't closed a bold tag). Presumably, the Vue routine that converts template HTML into Javascript script is super sensitive to this kind of glitch (unlike browsers which have been brilliant at coping with them for years) - so the template was silently failing.
I had to use a laborious "divide and conquer" process to track it down - chop everything out, then paste it back bit by bit. But there may be syntax checkers out there that would analyse your template markup thoroughly.
Worth checking.
The named v-slot can be used only in the template. Default can be used in the component too. See the docs: https://v2.vuejs.org/v2/guide/components-slots.html#Abbreviated-Syntax-for-Lone-Default-Slots
Also:
Note that v-slot can only be added to a (with one exception), unlike the deprecated slot attribute.
https://v2.vuejs.org/v2/guide/components-slots.html#Named-Slots

What do the hash marks (#) mean in Vue?

I am a rather new Vue developer.
Everywhere I go in our stack, I see code like this inside our components components:
<template #item.active="{ value }">
<div :aria-label="String(value)" class="text-center">
<v-icon v-if="value === null">mdi-minus</v-icon>
<v-icon v-else color="red">mdi-close</v-icon>
</div>
</template>
And for the life of me, I am cannot figure out what the #item.active (specifically the #) actually does. We have many hashed items. Like <template #item.actions-prepend="{item}"> or <template #toolbar-extension>
Googling a # isn't an easy thing to do.
And apparently I missed this specific video in my Vue tutorials!
We use Nuxt and Vuetify, not sure if that helps!
As mentioned in the comments, the # symbol is a shorthand for the v-slot attribute, as hinted by the usage of <template> (which v-slot only allows to be used on, as well as components) in your code.

Conditional scoped slot templates in vue

Can I not do something like this?
<template v-if="options.columns">
one thing...
</template>
<template v-else slot-scope="scope">
something else. scope doesn't work here. :(
</template>
When I try to do this, scope becomes undefined. The moment I remove v-if, else and use scope it works as expected.
I was facing with the exact same problem, what's worse, mine is failing silently - I didn't see any errors.
Solution #1 move if else condition to the inner scope of <template>
As David Japan pointed out, you can check if else condition in the inner scope of slot-scope:
<template slot-scope="scope">
<span v-if="options.columns">one thing...</span>
<span v-else>something else.</span>
</template>
Solution #2 use v-slot instead of slot-scope
<template v-slot="scope" v-if="options.columns">
one thing...
</template>
<template v-slot="scope" v-else>
something else.
</template>
However I don't know why v-slot fixes it, I searched both in the official documentation and online but no clues.
The solution is a workaround:
Create 2 different SFC for each possible use case and do conditional rendering.
Vuetify example:
// App.vue
<div>
<ListMD v-if="this.$vuetify.breakpoint.name === 'md'" />
<ListXS v-if="this.$vuetify.breakpoint.name === 'xs'" />
</div>
In Vue.js component you cannot have more than one template tag.
Why not using 'is' property for dynamic component ?
<template>
<div :is='my-component'></div>
</template>
So you can load a component dynamicaly.
https://v2.vuejs.org/v2/guide/components.html#Dynamic-Components

Action helper won't work inside handlebar's {{#if}}

I have a machine_list_item.html template which contains this piece of code:
{{#if view.machine.isGhost}}
<div class="remove-machine-key-association">
<button {{action "aloha" target="view"}}></button>
</div>
{{/if}}
And I have this function inside machine_list_item.js view:
aloha: function() {
alert('Tadah!');
}
The button won't call the function and will give this error:
Error: assertion failed: The action 'aloha' did not exist on Mist.MachineListItemView
However, if I comment out the handlebar's {{#if}} structure, the code will work just fine.
Any help will be appreciated!
Using {{#linkTo}} ... {{/linkTo}} implicitly creates a view. Many handlebars blocks do this. So anything inside the ... that refers to view is actually referring to the LinkToView.
To fix this, rename your view using {{#with ... as ...}} so that it doesn't get shadowed.
{{#with view as myView}}
{{#linkTo 'machine' myView.machine}}
{{#if myView.machine.isGhost}}
<div class="remove-machine-key-association">
<button {{action "aloha" target=myView}}></button>
</div>
{{/if}}
{{/linkTo}}
{{/with}}
See this question for more details.
I guess you have somewhere else a problem, here a simple example how it works correctly: http://jsbin.com/IhojaYE/2/edit
Hope it helps.

Meteor: Re-use template with different data

I've got a few templates which list items (log lines, users) and style them accordingly in tables. Now I've added a "search" page which searches for a string in different item types and displays them on one page. In terms of layout, I want to reuse the original templates, but obviously with the data returned by the search.
How can I do that without duplicating the template itself in the HTML file?
Put another way: How can I use the actual data from the top-level template in the sub-templates.
Small example:
<template name="user_list">
{{#each user_list}}
</template>
<template name="users">
{{> user_list}}
</template>
<template name="search">
{{> user_list}}
{{> group_list}}
</template>
In .coffee:
Template.users.user_list = ->
[a,b,c,d]
Template.search.user_list = ->
[b,c]
Maybe this is an easy one, which would show how little I really understood about Meteor.
Just put the template you want to use inside the {{#each}} statement. Then each item in the array will be the context for that inner template.
HTML file
<template name="users">
<ul>
{{#each UserArr}}
{{> userItem}}
{{/each}}
</ul>
</template>
<template name="userItem">
<li>{{username}} {{profile.name}}</li>
</template>
JS file
Template.users.UserArr = function()
{
return Meteor.users.find({});
};
another solution is to put your request in a Session attribute and check for its existence when querying for the users. By default Session.get("userQuery") would return undefined but once you enter something in the search field you change that with Session.set("userQuery", {type: "something"})
Now in the coffeescript you could say:
Template.users.user_list = ->
if(Session.get("userQuery"))
[a,b,c,d]
else
[b,c]
or alternatively use a MiniMongo query because it is much nicer :-)
the nice thing is that your HTML will rerender because it is reactive to the Session's content.

Categories