Iam getting started with MeteorJS/Iron Router/Blaze and I'm trying to figure out how to set placeholder for template.
I have a menu and a footer, which will change only partialy, but between them is the main content which should be based on current route. Point is that i need some sort of pointer, like in angular "ng-view".
Eg.
<menu></menu>
{{some sort of placeholder}}
<footer></footer>
and in router:
Router.route('/', function () {
//render some template exactly into placeholder, dont append it to the bottom
});
Maybe there is something wrong with my understanding of meteorjs templating, I just base my way of solving this problem on angular templating.
not sure I got your question but here is an answer:
You can do that with the {{> yield}} tag. It will define an dynamic area which will show the view corresponding to the current route.
You can also "design" a layout for your entire app, like you did, for example layout.html :
<template name="layout">
<div class="container">
<header class="navbar">
<div class="navbar-inner">
<a class="brand" href="{{pathFor 'home'}}">My app</a>
</div>
</header>
<div id="main" class="row-fluid">
{{> yield}}
</div>
</div>
</template>
And tell Iron-Router that your app has to fit this layout :
Router.configure({
layoutTemplate: 'layout'
});
// Then just define your routes
Router.map(function() {
this.route('home', {path: '/'});
});
You may notice I used {{pathFor 'home'}} in the layout. Iron Router let you use route "names" so it won't do anything if you change the URL.
I suggest you read an awesome book called Discover Meteor !
Related
In Ember.js (version 2.5.1), I have the following code in my application.hbs:
<div class="content-wrapper">
<section class="content-header">
<h1>
{{title}}<small>{{description}}</small>
</h1>
</section>
<section class="content">
{{outlet}}
</section>
</div>
Where should I declare {{title}} and {{description}} properties so they can change depending on the current route? I thought of generating an application controller (ember g controller application) which works fine for the index route, however, I am unable to change these properties if I navigate to other routes in my application.
I would design my application.hbs like this
{{partial "app_navbar"}}
<div class="container">
{{outlet}}
</div>
{{partial "app_footer"}}
And to create a route dependent header i would make a component content-header
templates/components/content-header.hbs
<div class="content-header">
<h1> {{params.title}} - <small> {{params.description}} </small> </h1>
</div>
And in your custom route's controllers
export default Ember.Controller.extend({
navbarParams: {
title: 'Foo',
description: 'Bar'
}
});
And in your custom route's template
{{content-header params=navbarParams}}
{{! Your other content here}}
I have a nested route that looks like:
/products
/products/:productId
And the /products template renders with a sidebar listing all the products, and a "main" content <div> in the center that is populated with a specific product when clicked. ie:
<div id="productsSidebar">
... navigation tree ...
</div>
<div id="mainContainer">
{{outlet}}
</div>
However, I would like for the {{outlet}} to be replaced with a message like
Please select a product to the left.
When there is no child route, ie. we're just looking at /products and the main <div> is otherwise completely empty.
I haven't found any reference/tutorial demonstrating if this is possible - is there a standard way to render a "default" block of HTML if there no outlet available?
You can use the products index route template to display that html text. You may need to generate the route with something like ember g route products/index
I'm trying to create a simple interface with a list of links on the left, retrieved from an AJAX call, that, when clicked, open in an {{outlet}} to the right with some data, retrieved as well from another AJAX call from that link. So these are my routes:
App.Router.map(function() {
this.resource('about');
this.resource('subreddit', { path: 'subreddit/:subreddit_name' }, function() {
this.resource('comments', { path: 'comments/:id' })
});
});
So I have a dynamic list of links, based on :subreddit_name with the following structure:
subreddit/:subreddit_name/comments/:id
To create the links I have the following codeblock:
<script type="text/x-handlebars" id="subreddit">
<div>
{{#each item in model}}
{{#linkTo 'comments' item.subreddit item.id classNames="list-group-item"}}
<img class="media-object" {{bindAttr src="item.thumbnail"}} class="img-rounded">
{{item.author}}
{{/linkTo}}
{{/each}}
</div>
<div>{{outlet}}</div>
</script>
The link is properly corrected, but, after I've inserted the :subreddit_name dynamic route to the Router, when I click the link it re-renders the whole template, instead of re-rendering only the template for the comments:
<script type="text/x-handlebars" id="comments">
{{#each item in model}}
<div class="panel panel-info mypanel">
<div class="panel-heading">{{item.author}}</div>
<div class="panel-body">
<p>{{{item.body}}}</p>
</div>
</div>
{{/each}}
</script>
I'm still pretty green on EmberJS, that's why I would like to ask for some suggestion/commment on out to correct this.
Thanks in advance!
Here is the jsbin working example:
http://jsbin.com/OlOJEwAX/4/edit?html,js,output
I've managed to get the links working but the undefined is also there rendered :S
I'm using the following Ember.js stack:
DEBUG: -------------------------------
DEBUG: Ember : 1.1.2
DEBUG: Handlebars : 1.0.0
DEBUG: jQuery : 2.0.2
DEBUG: -------------------------------
I declared an application.hbs Handlebars template which renders my App.ApplicationView
{{#view App.ApplicationView}}
{{outlet 'modal'}} {{outlet 'notificationCollection'}}
{{#if isUserAuthenticated}}
{{render sidemenu authenticationState=isAuthenticated}}
{{outlet 'upperNotification'}}
<div id="main" class="main">
{{outlet}}
</div>
{{else}}
{{outlet}}
{{/if}}
{{/view}}
and for debugging purposes I added the gotcha to the classNames array of App.ApplicationView. When I now inspect the DOM, I can see that App.ApplicationView is rendered twice (and also boxed):
...
<div id="appRoot" class="ember-application">
<div id="ember444" class="ember-view gotcha">
<div id="ember445" class="ember-view gotcha">
...more content..
</div>
</div>
</div>
...
EDIT:
I should have tried it first, before posting it here at stackoverflow... if I remove the {{#view App.ApplicationView}}{{/view}} declaration, it get's only rendered once, as expected ;)
So, the question which remains a miracle to me is is Ember.js really generating an enclosing <div id="ember666" class="ember-view"></div> for every {{outlet}}??
Why would Ember.js handle it this way? How can I prevent it from rendering App.ApplicationView twice? And, besides that, is Ember.js really generating an enclosing <div id="ember666" class="ember-view"></div> for every {{outlet}}? (I'm seeing this behaviour within my application)
By default, yes {{outlet}} will enclose your template in a <div>. However, you can change that behavior by specifying a view class on the outlet and defining the view class' tagName property to whatever you want.
For example, the outlet
{{outlet viewClass=App.HeaderContainer}}
With view
App.HeaderContainer = Ember.ContainerView.extend({
tagName: 'header'
});
will wrap the outlet in a <header> tag.
I am trying to render my application template, which is getting very complicated, so I want to split it up into separate <script type="text/x-handlebars">'s
I think I want to use the {{view}} helper, but I don't know. Let's say I have this:
<script type="text/x-handlebars" data-template-name="application">
<div id="wrapper" class="clearfix">
<hgroup>
<header>
<div class="logo"></div>
<h1 id="facilityName">{{facilityName}}</h1>
<div id="sessionInfo">
<a id="userName">{{user}}</a>
<a id="logOut" href="../logout">log out</a>
</div>
</header>
</hgroup>
{{view App.breadcrumbsView}}
</div>
</script>
And I want to load this next template inside of the one above:
<script type="text/x-handlebars" id="breadcrumbs">
<div id="breadcrumbs">
<p>
Network
{{#each breadcrumbObj}}
<span>></span><a {{bindAttr href="link"}}>{{name}}</a>
{{/each}}
</p>
</div>
</script>
Right now I am trying to do this with this code from my app.js
App.breadcrumbsView = Ember.View.create({
templateName: 'breadcrumbs',
breadcrumbObj: Util.breadcrumbs()
});
This is not working and I am getting Uncaught Error: assertion failed: Unable to find view at path 'App.breadcrumbsView'
Thanks
I think that you declared your App using var keyword. So it's not visible in handlebars template.
Change this
var App = Ember.Application.create();
To this
App = Ember.Application.create();
And you have to use extend instead of create when creating your views. Because ember will handle the object lifecycle like: create, destroy, add and remove binding etc.
#Marcio is right, you should .extend() and let the framework create it for you automatically by request. Furthermore when you extend the best practice is to use capitalized names like App.BreadcrumbsView.
See here a demo how it renders correctly doing it this way.
Hope it helps.