I am building an emberjs application I want to have two different layout for example application template and another template ,I don't want all my views to be rendered in the application template ,like in rails when you can specify to have multiple layouts for different controllers
Its actually pretty easy, just specify which template to render:
App.ApplicationRoute = Ember.Route.extend({
renderTemplate: function() {
if (expression) {
this.render('application');
} else {
this.render('site');
}
}
});
Via http://emberjs.com/guides/routing/rendering-a-template/
these is the answer I got from emberjs discussion forum
Create two views for the two layouts with the "layoutName" property:
App.MainLayoutView = Ember.View.extend({ layoutName: 'layout/main', });
and:
App.SecondaryLayoutView = Ember.View.extend({
layoutName: 'layout/secondary',
});
Create two templates for the layout, called "layout/main" and "layout/secondary".
Make sure that your views extends those layout views. For example, imaging the following route config:
App.Router.map(function() {
this.resource('users', function() { this.route('new');
this.route('login'); });
});
If you want all the users route to be using MainLayout and login to be using the Secondary layout, create two views:
App.ProjectsView = App.MainLayoutView.extend();
and
App.LoginView = App.SecondaryLayoutView.extend();
There is no need to create a view for "projects/new" because it is a nested route of projects, hence inheriting the layout of Projects.
Hope it helps!
Related
I'm pretty new to Ember and would like to get a selected models value in child controller/template.
I have a sidebar that lists Workspaces. Whenever someone click on workspace the application routes to workspaces/:slugand shows a list of tasks connected to that specific workspace.
I would like to show the selected workspace name in the child route. How would I go about doing that?
My router looks like so:
App.Router.map(function() {
this.route('login');
this.resource('workspaces', function() {
this.route('tasks', {path: ':slug'});
});
});
Been reading a lot of stuff online but haven't quite figured it out.
Thanks.
:slug is your dynamic segment. You can access your dynamic segment inside your model hook like so:
App.WorkspacesTasksRoute = Ember.Route.extend({
model: function(param) {
return { name: param.slug };
}
});
See a working jsbin example here
I currently render my templates manually like so:
App.IndexRoute = Ember.Route.extend({
renderTemplate: function() {
this.render('index');
this.render('nav', {
outlet: 'nav',
into : 'index'
});
this.render('welcome', {
outlet: 'welcome',
into : 'index'
});
}
});
Now this works fine, but its been brought to my attention that best ember practices avoid manually rendered templates.
So I can understand that my index template should and would be rendered automatically dude to Ember awesomeness. However, how do I control the rendering of my nav and welcome templates inside of my index template? Is that something I handle in the router, controller? Or should I do it with handlebar partials?
Thanks.
in the template where you have your outlets replace it with template renders
instead of
{{outlet nav}}
use
{{render 'nav'}}
and you can completely remove the render section for nav. After you've done the same for welcome you can delete the renderTemplate hook altogether.
Additionally, there is nothing wrong with using the renderTemplate hook, it's a very accepted practice, granted in your case unnecessary.
read more about the render helper here http://emberjs.com/guides/templates/rendering-with-helpers/#toc_the-code-render-code-helper
I have a view:
App.MyView = Ember.View.extend({
templateName: 'parent',
mouseEnter: function() {
// Do something
}
});
whose template has an {{outlet}}.
Here's the JS Bin: http://jsbin.com/ucanam/2779/edit
I'm trying to render into the outlet, and I can't figure out why it's not working. I tried putting the render call in an Em.run.next, because this issue is similar to https://github.com/emberjs/ember.js/issues/3626
Great question, but this isn't supported, here's some reasons:
The documentation specifies that the into is the route (http://emberjs.com/guides/routing/rendering-a-template/).
It's a dynamic view, which makes it an interesting problem, if you have multiple instances of the view, which would ember choose?
That being said you can still restructure the app to handle what you want
http://jsbin.com/ucanam/2785/edit
I am using the Backbone Boilerplate https://github.com/tbranyen/backbone-boilerplate and don't know what's the best way to handle more than one page. I cannot find answer that helps me understand easily. Basically, I am thinking of those options:
Should each page has a different config.js? Like config-userpage.js, config-homepage.js...?
Should I have different router.js for different page instead? Like router-userpage.js or router-homepage.js,...?
Should I just try a different boilerplate like https://github.com/hbarroso/backbone-boilerplate?
You can definitely try a different boilerplate, but I'm not sure that will
help. Multiple pages can be achieved in many different ways.
A good reference example for the Backbone Boilerplate is:
http://githubviewer.org/. I have released the entire thing as open source and
you can View how basic pages are added there.
You may want to get creative and make a Page model that handles what page
you're on and inside of each route set the new page title and which layouts to
use.
A very basic, proof-of-concept, implementation inside of app/router.js might
look something like this:
define([
// Application.
"app",
// Create modules to break out Views used in your pages. An example here
// might be auth.
"modules/auth"
],
function(app, Auth) {
// Make something more applicable to your needs.
var DefaultPageView = Backbone.View.extend({
template: _.template("No page content")
});
// Create a Model to represent and facilitate Page transitions.
var Page = Backbone.Model.extend({
defaults: function() {
return {
// Default title to use.
title: "Unset Page",
// The default View could be a no content found page or something?
view: new DefaultPageView();
};
},
setTitle: function() {
document.title = this.escape("title");
},
setView: function() {
this.layout.setView(".content", this.get("view")).render();
},
initialize: function() {
// Create a layout. For this example there is an element with a
// `content` class that all page Views are inserted into.
this.layout = app.useLayout("my-layout").render();
// Wait for title and view changes and update automatically.
this.on({
"change:title": this.setTitle,
"change:view": this.setView
}, this);
// Set the initial title.
this.setTitle();
// Set the initial default View.
this.setView();
}
});
// Defining the application router, you can attach sub routers here.
var Router = Backbone.Router.extend({
routes: {
"": "index"
},
index: function() {
// Set the login page as the default for example...
this.page.set({
title: "My Login Screen!",
// Put the login page into the layout.
view: new Auth.Views.Login()
});
},
initialize: function() {
// Create a blank new Page.
this.page = new Page();
}
});
return Router;
});
As you can see, this is an opinionated way of creating "pages" and I'm sure
other's have better implementations. At Matchbox, I have a very robust Page
model that does breadcrumbs and figures out which navigation buttons to
highlight based on the state. You can also create Routers inside your modules
to encapsulate functionality and expose the Page model on the app object so
that it's available throughout your application.
Hope this helps!
As you'll be able to tell from my question, I'm slowly learning EmberJS. I've read the great guide on routes and I felt ready to take on the world but then...
In my example, I thought the {{somethingView}} would be rendered and not the controller property {{somethingCtrl}}. Is this the correct behaviour? If so how would you render a property from the Ember.View?
The JS
window.App = Ember.Application.create({
ready: function() {
this.initialize();
}
});
window.App.Router = Ember.Router.extend({
root: Ember.Route.extend({
index: Ember.Route.extend({
route: '/',
connectOutlets: function(router) {
var controller = router.get('applicationController');
controller.connectOutlet('garments');
}
})
})
})
window.App.ApplicationView = Ember.View.extend({
templateName: 'application',
});
window.App.ApplicationController = Ember.Controller.extend();
window.App.GarmentsController = Ember.Controller.extend({
somethingCtrl: "Something in the controller"
});
window.App.GarmentsView = Ember.View.extend({
templateName: 'garments',
somethingView: "Something in the view"
});
The DOM stuff
<script type="text/x-handlebars" data-template-name="application">
<h1>Hi Ember</h1>
{{outlet}}
</script>
<script type="text/x-handlebars" data-template-name="garments">
<h1>Garments</h1>
{{somethingView}}<br>
{{somethingCtrl}}
</script>
The Fiddle
This behaviour is correct. These are my understandings of these ember core concepts:
Model: These objects represent the date that is handled by your application. These are the business objects that form the domain model of your Application.
Controller: A Controller is responsible for providing access to your models. Controllers have the property content, where models should be injected (a single Object for Ember.Controller and an array of objects for Ember.ArrayController). The Controller passes this content to your View. The Controller is the default context for your view. Therefore the behaviour you describe is expected.
View: The View is just intended for displaying issues. I personally use it mainly to do jQuery animations.
But nonetheless it is possible to access the view instance in the template. You just have to use the variable with the name 'view' in your template. I updated your fiddle with a working example: http://jsfiddle.net/jPK8A/5/
<script type="text/x-handlebars" data-template-name="garments">
<h1>Garments</h1>
{{view.somethingView}}<br>
{{somethingCtrl}}
</script>
But to be clear: The most common case should be to access contents from your controller. It should be not often that you access variables of your view. You want to display date in your App and this date resides in models and should therefore be accessed through controllers. The most likely case might be, that you want to store labels in your view or something like that (labels that have to be computed).