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
Related
I want to insert a component into controller template without using the handlebars helper (component "component-name"... or component-name). Or through a controller in an outlet (or as long as the solution works for a component that wants to insert another component, then it's fine, I don't think outlets work in components).
In other words:
App.IndexController = Ember.Controller.extend({
actions: {
insertComponent: function() {
var component = this.container.lookup("component:my-inserted", { singleton: false });
component.set("layoutName", "components/my-inserted");
// to be like handlebars-inserted component, what do i do here?
}
}
});
You can use test with this: http://emberjs.jsbin.com/popozanare/4/edit?html,js,output
Why?
Thinking of a way of to have clean modal syntax, such as the "openModal" syntax described in the Ember Cookbook: http://guides.emberjs.com/v1.10.0/cookbook/user_interface_and_interaction/using_modal_dialogs/.
The problem is that the source context is lost, as the modal is within the ApplicationRoute. I want the same syntax when calling a modal, but keeping the hierarchy. You can keep the hierarchy using https://github.com/yapplabs/ember-modal-dialog, which requires a mapping of variables... which i don't like either (but will likely implement if I have no other choice).
TD;LR: Want to open modal within the controller/component (context) that called it without scaffolding in the controller/component that called it (mapping variables, etc).
Edit:
On second thought, using a container view might be cleaner than mapping variables, found in this solution: http://jsbin.com/hahohi/1/edit?html,js,output. Still needs scaffolding though. Thanks #user3568719.
That cookbook is a bit outdated, but if you are looking for a "clean" way to handling modals in your app I would suggest named outlets.
Add it to your application or auth template {{outlet "modal"}} and when you want to bring up the modal you can catch the action on the corresponding route and then render into that named outlet like so:
this.render('your-desired-modal-template', {
into: 'auth',
outlet: 'modal'
});
And when you want to dismiss it simply disconnectOutlet like so:
this.disconnectOutlet({
outlet: 'modal',
parentView: 'auth'
});
This is the way we've been going about it, I m open to suggestions/better methods.
Here's a JSBin demonstrating an issue I'm experiencing. This is the code for it.
I've run into a situation where if I navigate to a route in Ember.js after the application has been loaded (e.g. using transitionTo), everything works. But if I try to navigate to the route directly (by entering the url or refreshing the page once I'm already on the route) it doesn't render correctly.
I'm using renderTemplate to place the template into a parent route. But the parent route hasn't been rendered yet when visiting the route directly, so it fails with the following error in the console:
Cannot read property 'connectOutlet' of undefined
How can I ensure that the parent route's template is in place to avoid this error?
When you render a template into another template programmatically the other template must have already been rendered. You can schedule it to render after it's finished rendering.
App.BarRoute = Ember.Route.extend({
renderTemplate: function() {
var self = this;
Em.run.schedule('afterRender', function(){
self.render('bar', {into: 'baz'});
});
}
});
Example: http://jsbin.com/qilem/1#/bar
Really you're fighting the ember router heavily here. The application template should have an {{outlet}} defined inside of it, but when you use render you've created a nested scope where the outlet no longer exists in the application template. You can either use partial or pull the {{outlet}} out of the nested template.
Example Partial: http://jsbin.com/qilem/2#/bar
Example Render: http://jsbin.com/qilem/3#/bar
I am trying to make a simple app using Ember.js. I am using yeoman ember.
I have following application template
<h1>Dashboard</h1>
<div class="content">{{outlet}}</div>
I have a few routes defined. Now what I am not being able to do is, find a way to update the text inside <h1> for different routes. For example,
if I navigate to /#/users I need it to change to Users.
if I navigate to /#/users/1 I need it to change to the model's firstname.
I tried this in ApplicationRoute
setupController: function(controller){
controller.set('title', 'Dashboard');
}
and changing to <h1>{{title}}</h1>
but it only works for ApplicationRoute and no other route!
setupController: function(controller){
controller.set('title', 'Users');
}
This does not work in UsersRoute. Even the output of the route disappears.
What is the right approach to get this to work!
How about you simply create an action in ApplicationRoute that sets the title as passed to it as an argument, and then have your sub route call that action in setupController. That should do the trick.
So in you application route:
//in application route
actions:{
updatePageTitle: function(title){
this.controllerFor('application').set('title', title);
}
}
And in your individual child route:
setupController:function(controller, model){
this.send('updatePageTitle', model.get('something'));
this._super(controller, model);
}
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
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).