Display dynamic content in Ember application template - ember.js

I am creating an Ember app that manages a list projects and tasks for each project. In the app's navigation, I want to display the name of the selected project. If someone navigates to /projects/1/tasks, I want the page to display project 1's title, along with links to pages specific to that project. Here is what I have started for my application.hbs file of how I expected it to work, however the project title is blank and the links don't work:
<nav id="nav-menu">
<ul>
<li class='menu-project-title'>
{{#link-to 'projects'}}{{project.title}}{{/link-to}}
</li>
<li class='menu-separator'> </li>
<li>{{#link-to 'projects.tasks' project}}Tasks{{/link-to}}</li>
<li>{{#link-to 'projects.people' project}}People{{/link-to}}</li>
</ul>
</nav>
<div class="container" id='main-outlet'>
{{outlet}}
</div>
If I know every route will always have a project returned, what is the best way to pass that data into the application template?

You could use an Ember.computed.readOnly property in your application controller.
App.ApplicationController = Ember.Controller.extend({
needs: ['project'],
activeProject: Ember.computed.readOnly('controllers.project.model')
...
});
But maybe this isn't the best solution. As far as I understand it, the project route/template is always used? So why not move everything to that template.

Related

Ember how to update isAuthenticated after logging in

I have an app setup using ember-cli 0.1.1 and I'm using ember-simple-auth (along with devise cli plugin) for login. In my application template, I have a menu with a conditional wrapped around it:
{{#if session.isAuthenticated }}
<div class="nav_user">
<p>{{session.user_name}}</p>
<p class="user_account">{{#link-to 'account-settings'}}<img src="assets/images/gear.png" />{{/link-to}}</p>
</div>
<ul>
<li>{{#link-to 'horses'}}My Horses{{/link-to}}</li>
<li>{{#link-to 'veterinarians'}}Veterinarians{{/link-to}}</li>
<li>{{#link-to 'documents'}}Documents{{/link-to}}</li>
<li>{{#link-to 'notes'}}Notes{{/link-to}}</li>
</ul>
<ul>
<li><a {{action 'invalidateSession'}}>Logout</a></li>
</ul>
{{/if}}
The problem is that after a successful login, I transition to another route and if I immediately open the menu, the non-authenticated menu is what appears. If I refresh, then I get the correct menu contents. I'm looking for a way to updat session.isAuthenticated after a successful login, prior to transitioning to the new route. Thanks in advance for any help.

how to get the generated Ember.Component HTML

I am using Emberjs and Gridsterjs to create some kind of editor. I found out that you need to make a component to include a jQuery plugin in Emberjs. Inside that component i have a number of components that will become the widgets for the Gridster.
this is how i've setup my templates:
<script type="text/x-handlebars">
{{#create-gridster}}
{{create-widget}}
{{/create-gridster}}
</script>
<script type="text/x-handlebars" data-template-name="components/create-gridster">
<button class="btn" {{action 'newWidget'}}>add widget.</button>
<section class="gridster-wrapper">
<div class="gridster">
<ul id="gridster-list">
{{yield}}
</ul>
</div>
</section>
</script>
Now i've created a button that allows the user to add a widget to the Gridster, but i can't seen to find a way to give the requested HTML string for the widget from the component.
I've tried this:
this.get('gridster').add_widget(Ember.Handlebars.compile('{{create-widget}}'));
and this:
this.get('gridster').add_widget(App.CreateWidgetComponent.create().createElement());
but that doesn't seen to work.
QUESTION
My question is how do i create the html string that gridster expects and keep the ember functionality for editting the content.
In myprettycms (myprettycms.codeplex.com) I use gridster to create layout, then to edit the content of the gridster li, I superpose a tiny mce on the slot and I transfert the content of the slot to tinyMCE instance.
When it's finish, I transfert TinyMCEContent in the slot.
See : http://myprettycms.codeplex.com/SourceControl/latest#MyPrettyCMSCommunityManager/Portals/MVC4Portal/Scripts/Views/DynaContentAdmin.js

Remove the rendered application template

I have quite many templates that I render into the application template. The application template, however, has only the {{outlet}} and nothing else.
The home template, must render directly into the application template. But all other templates must be rendered along with the navbar and sidebar.
Currently, I am using partial to render the common data in all the other templates (except 'home')
How can I solve this scenario? All I need is that home should render directly in the body, while all the other templates must render along with the navbar and sidebar.
I might be missing something very obvious here. What should I do to render home in one template and the rest in another?
UPDATE 1
Application Template
{{#unless renderNav}}
{{outlet home}}
{{else}}
{{partial 'navbar'}}
<div class="container">
<div class="row row-offcanvas row-offcanvas-right">
<div class="col-xs-12 col-sm-9">
{{outlet}}
</div>
<div class="col-xs-6 col-sm-3 sidebar-offcanvas" id="sidebar" role="navigation">
<div class="list-group">
Link
Link
</div>
</div><!--/span-->
</div><!--/row-->
</div><!--/.container-->
{{/unless}}
UPDATE 2
The above code causes rendering problems. Navigating to the home template causes no issue. But in all other templates, the first page rendered stays on the top while the next pages are rendered below it.
For example, if after 'home', I transition to 'first', 'first' renders two elements A and B.
If I next transition to 'second', which renders C, what I get is A and B and C, instead of C.
UPDATE 3
Solved the error in the previous UPDATE by observing the currentPath property in the application controller. But now in the 'home' route, the 'home' template is not displayed. Instead the navbar is rendered with an empty outlet.
I renamed my outlets and forced HomeRoute to render into outlet 'home'. But still there is no change. All other templates are rendered seamlessly, but 'home' is not rendered at all.
I confirmed that the boolean was false in the HomeRoute, but still the navbar template is being rendered.
You can create a template where navbar and sidebar can be rendered in and all templates except home are nested routes of this new template.
This of course can give you trouble with url, so another way to go is to use a boolean computed property in the application controller based on currentPath that renders or not your partials
e.g.
App.ApplicationController = Ember.Controller.extend({
showPartials: (function() {
this.get('currentPath') != 'home'
}).property('currentPath')
});
Then in your application template do something like
{{#if showPartials}}
{{partial "navbar"}}
{{partial "sidebar"}}
{{/if}}

Ember.js - default template to render into an outlet?

So I have a page which looks like the following
[ Nav Bar ]
| |
| Content |
| |
The nav bar I want to be constant across all pages. So the approach I used was to set my page up as follows:
[ Nav Bar ]
{{outlet}}
This is great, I can now render different pages into my outlet for different routes.
But what if I want a default template to be rendered into the outlet for my home page?
I've managed to achieve this by redirecting / to /home, but there must be a better way to do this which allows me to render a default home page at / without re-routing?
Any advice appreciated,
Thanks,
Daniel
To render stuff in the {{outlet}} at the root page /, you have to define a handlerbar script for index:
Your navbar code probably look like this:
<script type="text/x-handlebars">
<div class="navbar ...">
...
</div>
{{outlet}}
</script>
The root page that will be place inside {{outlet}} is the fallowing:
<script type="text/x-handlebars" id="index">
<div class="container">
<h1>Root page!!</h1>
</div>
</script>
In other words, you have to create a handlebar script that will have an id="index".
Should work. It doesn't need any js code to work.
I must admit this property is not well documented and buried in the docs for Ember.View but you could try setting the defaultTemplate property on your ApplicationView. See here for more info on that (search in the page for 'defaultTemplate').
Hope it helps.
The following statement in docs helped me to solve exactly the same problem I was having which is stated in the question:
Ember routing docs
The index template will be rendered into the {{outlet}} in the application template. If the user navigates to /favorites, Ember will replace the index template with the favorites template.
As I am using pod structure in my project, I created an index route having my default template and I placed nav-bar component in my application/template.hbs file.
app/application/template.hbs:
<div id="pageWrapper">
<div id="navbarfixed">{{nav-bar options=options}}</div>
<div id="pageContent">
{{outlet}}
</div>
</div>
app/index/template.hbs
<div id="homeWrapper"> <!--This gets rendered by default in outlet above-->
Some default content of outlet
</div>

Change Navbar based on login state

I’ve been trying, using Rails/Ember pre-4, to do a fairly typical thing, that is have a page with a navbar and a content section. The navbar only changes on login (shows logout button when logged in and login and register buttons when logged out), not on every page change.
At first thought i could do something in the application.hbs template such as:
{{view navbar}}
{{outlet}}
where i set up navbar to respond to login state changes (managed by a state manager). This didn’t seem to work.
Then i tried something like (also in application.hbs):
{{outlet navbar}}
{{outlet}}
and tried setting navbar in each route, which results in lots of duplication and also didn’t ultimately work.
Before posting code, wanted to know if anyone already has a good solution to this common situation where certain parts of your page such as a navbar or sidebar only change upon some change in app state, not on every page change.
There are lots of ways to get this done. The first approach you described is closest to what we are doing. In past ember versions we used view helper for this, today we use {{render}} but it's the same basic concept. For example, application.hbs might look like this:
{{render navbar}} {{outlet}}
Now navbar.hbs can use a simple {{#if}} helper to swap links based on login state.
<div class="navbar">
<div class="navbar-inner">
{{#linkTo index class="brand"}}My App{{/linkTo}}
<ul class="nav">
<li>{{#linkTo index}}Home{{/linkTo}}</li>
<li>{{#linkTo about}}About{{/linkTo}}</a></li>
</ul>
<ul class="nav pull-right">
{{#if isAuthenticated}}
<li><a {{action logout}} href="#">Logout</a></li>
{{else}}
<li><a {{action login}} href="#">Login</a></li>
{{/if}}
</ul>
</div>
</div>
Now we add logic to NavbarController that tracks and manages login state.
App.NavbarController = Ember.ArrayController.extend({
isAuthenticated: false,
login: function() {
this.set('isAuthenticated', true);
},
logout: function() {
this.set('isAuthenticated', false);
}
});
In a real app NavbarController would proxy these requests to another controller, perhaps currentUserController. I've created a working sample here: http://jsbin.com/iyijaf/6/edit