Ractive binding to parent - javascript

I have a simple template for posts with comments:
{{#each Posts}}
{{Text}}
{{#each Comments}}
//how can I bind to Post.Id here? Like {{../Id}}
{{/each}}
{{/each}}
How can I bind to a parent #each block (I need to get post's Id property) inside comments #each block?

Ractive supports Restricted References, so just like you have it:
{{#each Posts}}
{{Text}}
{{#each Comments}}
Post Id: {{../../Id}}
Comment Id: {{Id}}
{{/each}}
{{/each}}
You can also alias Parent fields if you don't need bidirectional updates on the aliased field:
{{#each Posts}}
{{Text}}
{{#with { PostId: Id } }}
{{#each Comments}}
Post Id: {{PostId}}
Comment Id: {{Id}}
{{/each}}
{{/with}}
{{/each}}

Related

Checking equality in Blaze?

The user can only delete a post if he was the one who posted it.However a user can see all the posts.The javascript code is:
var postedBy = Meteor.user();
var currentPost = this._id;
Posts.insert({
name:postName,
createdAt:new Date(),
postId:currentPost,
postedBy:postedBy
});
The HTML code is:
<template name="posts">
{{#if currentUser}}
{{> addPost}}
<ul>
{{#each post}}
<li>{{> postItem}}</li>
{{/each}}
</ul>
{{/if}}
</template>
<template name="postItem">
<li>
<h4>{{name}}</h4>
<i>Posted by {{postedBy.username}} on {{createdAt}}</i>
[Delete]
</li>
</template>
<template name='addPost'>
<input type='text' placeholder='Add post here' name='postName' id ='myinput'>
<button class="btn btn" type="button" id='btn'>Post</button>
</template>
Both currentUser.username and postedBy.username are displaying the names of the logged in user and the user who posted a particular post respectively.
I am trying to work with the Delete anchor tag.
{{#if currentUser.username==postedBy.username}}
[Delete]
{{/if}}
But it shows error in command prompt.I know it is wrong but I can't think of any other way.How do i write this 'if' statement to check if the current user was the one who posted this post?
Please help as I am new to Meteor.Sorry for bad English.
You can't use arbitrary JavaScript expressions in spacebars. Add a helper like this:
Template.postItem.helpers({
canDelete: function (){
return Meteor.user().username === this.postedBy.username;
}
});
Which you can then use in your template like this:
{{#if canDelete}}
Delete
{{/if}}
Also note, instead of copying the user object into each post, the recommended way is to store the user's id in postedBy.

Meteor.js affecting only newly inserted child template

These are templates:
<template name="postsList">
{{#each posts}}
{{>postItem}}
{{/each}}
</template>
<template name="postItem">
<div class="more-less">
<div class="more-block">
<p>{{{text}}}</p>
</div>
<p class="continued">…</p>
[ + ]
</div>
</template>
When posts is updated with new post, postItem is inserted to postsLists. How can I apply this only for new inserted postItem template:
$('.more-less .more-block').css('height', 20).css('overflow', 'hidden');
Template.postItem.rendered affects all posts in page, but I need to affect only newly inserted post without affecting existing ones.
I'm going to assume new posts are added to the top of the list? if so...
<template name="postsList">
<div class="posts-list">
{{#each posts}}
{{>postItem}}
{{/each}}
</div>
</template>
<template name="postItem">
<div class="more-less">
<div class="more-block">
<p>{{{text}}}</p>
</div>
<p class="continued">…</p>
[ + ]
</div>
</template>
You can simply achieve this with CSS:
.posts-list .more-less:first-child .more-block {
height: 20px;
overflow: hidden;
}
No need to use JavaScript and worry about reactivity and DOM mutation.

How Do I Return Template From Meteor Template Helper?

My HTML:
<template name="foo">
{{#each category}}
{{#if this.custom}}
{{> someTemplateName}}
{{else}}
{{> generic}}
{{/if}}
{{/each}}
</template
How do I return some value to `someTemplateName' so that I can switch templates based on on the object in the #each statement.
Template.foo.someTemplateName = function () {
return A_TEMPLATE_NAME
}
Thanks.
The correct syntax is the following :
JS
Template.foo.helpers({
someTemplate:function () {
return Template.someTemplate;
}
});
HTML
<template name="someTemplate">
<p>SOME TEMPLATE</p>
</template>
It is not really the name that you manipulate but template objects which live under the variable name Template.myTemplate.
If you want to manipulate template names, try UI.dynamic :
HTML
<template name="foo">
{{> UI.dynamic template=someTemplateName}}
</template>
JS
Template.foo.helpers({
someTemplateName:function () {
return "someTemplate";
}
});
The solution was actually very simple.
<template name="foo">
{{#each category}}
{{#if this.custom}}
{{> someTemplateName}}
{{else}}
{{> generic}}
{{/if}}
{{/each}}
</template>
And I return a helper:
Template.foo.someTemplateName = function () {
return Template[this.name];
}
Where this.name is from the `{{#each}}' context.

Sending data into a nested Controller/View in EmberJS

I'm messing around with JSON structures in EmberJS starting from the top level Application level and trying to pass data to a general MenuController/MenuView child so I can reuse it.
The JSON I've come up with to play around with how data gets passed through nested ember structures is this:
JSON
{
appName: "CheesyPuffs"
menuItems: [
{name:"Gouda"}
{name:"Crackers", menuItems: [
{name: "Cheezeits"}
]
}
]
}
Handlebars
<script type="text/x-handlebars">
<div class='app'>
<div class='header'>
{{#if menuItems}}
// Embed template 'menu'
{{/if}}
</div>
</div>
</script>
<script type="text/x-handlebars" data-template-name="menu">
<ul>
{{#each menuItems}}
<li>{{name}}</li>
{{#if menuItems}}
// Embed menu template
{{/if}}
{{/each}}
</ul>
</script>
JS
App.MenuController = Ember.ArrayController.extend({
actions: {
click: function(){
// Signal Event to App
}
}
});
App.MenuView = Ember.View.extend({
click: function(){
console.log("I clicked a menu");
}
});
All the examples I've seen concerning nested stuff involves routes with the classic _id subroute. I'm not sure how I would go about telling the App Router that it needs to pass the menuItems data to a child controller that's embedded in the same view. I have a feeling you can do this both via the template and programmically? If so, how would you do it both ways?
using the template you should use render. And that's the way you should do it, programmatically doesn't make sense.
<script type="text/x-handlebars">
<div class='app'>
<div class='header'>
{{#if menuItems}}
{{render 'menu' menuItems}}
{{/if}}
</div>
</div>
</script>
<script type="text/x-handlebars" data-template-name="menu">
<ul>
{{#each menuItems}}
<li>{{name}}</li>
{{#if menuItems}}
{{render 'menu' menuItems}}
{{/if}}
{{/each}}
</ul>
</script>

Ember.js using each, get count

Using Ember.js with handlebars, and looping through results like:
{{#each transaction in transactions }}
<p>Transaction: {{ transaction.name }}</p>
{{else}}
<p>No results...</p>
How can I look at the total count of transactions and if greater than 10, add a simple load more:
<p><a {{action loadMoreResults}}>Load more transactions...</a></p>
Implement a custom handlebar helper, something like if_gt
{{#if_gt transactions.length compare="10"}}
<p><a {{action loadMoreResults}}>Load more transactions...</a></p>
{{/if_gt}}
And your Helper will be defined something like this
Handlebars.registerHelper('if_gt', function(context, options) {
if (context > options.hash.compare)
return options.fn(this);
return options.inverse(this);
});
In that case you can try this.. just move the element to outside the loop
{{#if something}}
{{#each transaction in transactions }}
<p>Transaction: {{ transaction.name }}</p>
{{/each}}
{{else}}
<p>No results...</p>
{{/if}}
{{#if_gt total_transactions compare="10"}}
<p>Load more...</p>
{{/if_gt}}

Categories

Resources