I have a hierarchy of nested routes in my ember app. I want one of the child routes to bypass rendering it's parent template and render directly into the application template. However, I still want to keep the route hierarchy, because I need the models from the parent routes in the child route. What I did is I defined the renderTemplate hook on the child route to render into the application:
renderTemplate: function() {
this.render({ into: "application" });
}
This works, but when I then click on a link to the parent route, nothing is rendered. I put together a small jsfiddle to demonstrate this: http://jsfiddle.net/H7gvz/1/ - run it, then click on one of the names, then click on "Index". I expect the PeopleRoute to render the people template but instead nothing is rendered.
Is this a bug or am I doing it totally wrong? What should be the correct way to do this?
Whenever you use nested routes, transitioning from child route ('people.show') to parent route ('people'), will be redirected to the 'index' route. Rendering your 'people' template in App.PeopleIndexRoute will solve your problem.
App.PeopleIndexRoute = Em.Route.extend({
renderTemplate: function() {
this.render('people',{ into: "application" });
}
});
Your working fiddle
Related
I'm using React Router and I'm trying to link to a sub-component in another route by id. Basically what would usually be done using the <a href="www.url.com/profile/#profile-header-id">.
I'm not sure if there's a built in way for react router to do this, but if not perhaps I can manually trigger the link at a later point when I know the element has been rendered.
The issue isn't linking to another route which of course is done with the Link from react router. The issue is linking to an element which is found in the rendered HTML of the linked component.
Less Abstract Code Example:
So let's say my router is
<Route path"/A" component={A}>
<Route path"/B" component={B}>
component A has the following render:
render(){
<div>
// A looooot of text and other HTML elements
<div id="relevant-to-B">
// relevant stuff for component B
</div>
</div>
}
Now in component B, I want a Link that not only takes me to the Route "/A", but also scrolls to the element of id #relevant-to-B, thereby skipping all the irrelevant stuff.
Routing in Ember.js is troubling me, and I can't seem to find the "correct" way of doing what I want to do.
I have a route, let's call it #/map, which contains a series of top-level and containers of child views.
Hierarchically, I have a top map_view, which contains 4 additional views: A topbar (which has topbar menu item triggers within it), a sidebar (which has sidebar menu item triggers in it), and two containerViews (a sidebar menu containerView and a topbar menu containerView), which will contain one or more nested views that are programatically inserted on clicking a menu item trigger.
My issue is that while this works, and I can embed all of these views into their various templates, none of them are linking with controllers, and the controller they are picking up is the map_controller (which makes sense as that is the linked outlet controller for the top level view). Currently I am using a method described on Ember's github here, but it seems a little...hacky?
Here is a JSFiddle showing the problem. Notice that the controller for level-one-entry and level-two-entry is the index_controller: http://jsfiddle.net/fishbowl/Z94ZY/3/
Here are some code snippets for what I am doing to get around it:
map.hbs:
<section id='map'>
{{view App.SidebarView}}
{{view App.TopbarView}}
<div id='map-canvas'></div>
</section>
topbar_view.js:
var TopbarView = Em.View.extend({
templateName: 'topbar',
classNames: ['topbar-container'],
init: function() {
var content = this.get('content'),
controller = App.TopbarController.create({
view: this
});
this.set('controller', controller);
this._super();
}
});
module.exports = TopbarView;
topbar_controller.js
var TopbarController = App.ApplicationController.extend({
content: Ember.computed.alias('view.content'),
trigger: null,
start_date: null,
end_date: null,
travelling: null,
word: 'topbar'
});
module.exports = TopbarController;
I'm not doing anything special in the router other than declaring this.route('map'). A further problem i'm having is that whenever I declare needs: ['some_other_controller'], I get an error
<App.TopbarController:ember413> specifies 'needs', but does not have a container. Please ensure this controller was instantiated with a container.
Am I missing something blindingly obvious about how to go about linking these together. I'm guessing that i'm using routing incorrectly. I don't want to change what the URL is, as i'm technically not moving pages, just opening and closing menus on the page, but I don't really understand how else i'm supposed to use the router to achieve this.
EDIT 2: i've mocked up another jsfiddle of what I could do with outlets and link-to's, but i'm not sure that I want the URL changing (as you'd probably be able to do odd things with the back button etc): jsfiddle - The alternative to this is to set location: 'none' in the Router, but I don't really like that option either...
My goal:
I want to make a compact, reuseable modal. It should take a template name, and render in a modal,
What i got so far:
http://emberjs.jsbin.com/mehabivu/6/edit
How it works:
App.ApplicationRoute has an action, which takes a template name.
It renders it into {{ outlet modal }}
I can use this action
application wide, and reuse templates
My problem:
I dont know how to wrap the outlet into a div or something (to add
css), and show/hide it.
Maybe there is a better practice (component?)
to do this
Sounds like your on the right path. Pretty much exactly what Ember says to do in their cookbook: http://emberjs.com/guides/cookbook/user_interface_and_interaction/using_modal_dialogs/
Wrapping/styling the modal can be done via the view you render into the outlet. Right now your menu2 template doesn't have a view.
App.Menu2View = Ember.View.extend({
tagName: 'section',
classNames: ['modal']
});
The above makes the containing tag a section and adds the modal css class to that container section.
I've updated your JSBin: http://emberjs.jsbin.com/mehabivu/7/edit
I have the below route structure.
App.Router.map(function() {
this.resource('projects', function() {
this.resource('listings', {path: '/:project_id/listings'}, function() {
this.route('listing', {path: '/:property_code'});
});
});
});
I replicated this structure and created a fiddle.
Fiddle: http://jsfiddle.net/aqHnt/6/
I hope the router is self-explanatory. I have a bunch of projects which each have a bunch of listings and each listing will have some additional details. Because these are nested resources, each child resource renders in to the {{outlet}} of it's parent template.
What I need is to entirely overwrite the parent template and as per a suggestion in a different post, I'm using the resources index route to achieve this.
So If you click on a project, the entire projects template will be replaced with the listings template. It's all good up to this point but I can't seem to achieve the same with listings. When I click on a listing, I want the entire listings template to be replaced by listing details. Can someone point out what am I doing wrong here.
Here is a possible solution: jsfiddle.
You were missing the listings template besides the listings/index one, as well as the route ListingsIndex. This way you replicate the same pattern you use at application level.
You could also consider using renderTemplate to specify in which outlet you need to render a given template.
Hope it helps!
I try to develop a simple Ember.js app.
I think that these screens describe the desired scenario good enough.
Buttons on the top are #link-tos. Note that I want the first button to be highlighted on the 3rd screen.
It's easy to find examples where the 3rd template lives in the outlet in the 2nd one, but I need some kind of template replacement in the main outlet.
Please help me to achieve this behavior. Hope that my description is clear enough.
You can make list and detail routes same level, so they both are rendered to the same outlet, one at time. Like that:
App.Router.map(function() {
this.resource("movies", function() {
this.route("list");
this.route("view", {path:"view/:movie_id"});
});
});
App.MoviesIndexRoute = Em.Route.extend({
redirect : function() {
this.transitionTo('movies.list');
}
});
All the rest is done as allways