Nested resources and path - javascript

I'd like to nest resources in Ember, but to be able to access them with a short URL.
For example: mysite.com/admin will open the route: /routes/profiles/settings/admin
Is it possible to do something like that using Ember?
I'm currently using Ember 1.7 with Ember App Kit.
I tried the following but it doesn't work:
var Router = Ember.Router.extend();
Router.map(function () {
this.resource('profile', function () {
this.resource('profile.settings', { path: '/settings' }, function () {
this.resource('profile.settings.admin', { path: '/admin' });
);
});
Thanks.

Your code doesn't work because your inner most resource is inheriting the /profile path from the outer most resource and /settings from the middle resource. If you want it to be just plain /admin, you'd have to do something like this:
this.resource('profile', { path: '' }, function() {
this.resource('profile.settings', { path: '' }, function() {
this.resource('profile.settings.admin', { path: '/admin' });
});
});
However, this is going to get pretty hairy when you have more routes that each want top-level paths. You might find it easier to just declare a admin route at the top level, then redirect using the redirect hook in the route.

Related

How to do routing with Electron and Vanilla Javascript

I have been looking for ways to find a way to make a single page application with vanilla javascript only but sadly I could not find one.
I found this code in a tutorial on how to make a SPAs, however the issue is location.pathname returns not the URL path but the file path instead with Electron. This bit of code is integral to make the routing work. And I don't wanna use any frameworks.
const router = async () => {
const routes = [
{ path: "/", view: console.log("Viewing /") },
{ path: "/login", view: console.log("Viewing login") },
{ path: "/dashboard", view: console.log("Viewing dashboard") },
];
const potentialMatches = routes.map((route) => {
return {
route: route,
isMatch: location.pathname === route.path,
};
});
};
window.addEventListener("load", () => {
router();
});
Is there a way I could retrieve the URL path and inject it to my index.js?

Switching from iron router to flow router

I'm new to meteor and coding in general. I need to change this to flow router so that I can get the comments to work(I guess). Does anyone want to lend a hand?
Router.map(function () {
this.route('post/:id', {
waitOn: function() {
return [
Meteor.subscribe('post', this.params.id),
Meteor.subscribe('postComments', this.params.id)
]
},
data: function() {
return {
post: Posts.findOne({_id: this.params.id}),
comments: Comments.find({postId: this.params.id})
}
}
});
});
And btw I'm using flow router on everything in the app so I guess iron conflicts with it which gives me this:
Oops, looks like there's no route on the client or the server for url: "http://localhost:3000/recipe-book."

Using Ember initializers to set domain related data

I have a single Ember app that needs to use different data depending on the domain that it's running on. For example, on domain1.com the site title might be "Domain 1 Website", whereas for domain2.org the site title could be "Cool Site!"
I need to be able to use the data in routes, controllers and templates.
My initializer so far:
import { request } from 'ic-ajax';
export function initialize(container, application) {
var domain = document.location.host;
return request('http://api/sites?domain=' + domain, {} ).then(function(response) {
// make the response available to routes, controllers and templates
});
}
export default {
name: 'site-data',
initialize: initialize
};
If you take a look at the docs:
http://guides.emberjs.com/v1.10.0/understanding-ember/dependency-injection-and-service-lookup/#toc_dependency-injection-with-code-register-inject-code
The second example
Ember.Application.initializer({
name: 'logger',
initialize: function(container, application) {
var logger = {
log: function(m) {
console.log(m);
}
};
application.register('logger:main', logger, { instantiate: false });
application.inject('route', 'logger', 'logger:main');
}
});
and the following explanation shows you how you can use .inject to make one of your variables, services or functions available to whatever objects you need within your application.

Ember parent route redirection to child route

My routes looks like this:
App.Router.map(function () {
this.resource('index', { path: '/' }, function() {
this.resource('label', { path: '/label' }, function() {
this.route('notes', { path: '/:label_id' });
});
this.route('manage', { path: '/manage' });
});
});
Users should only visit label.notes and manage routes. I'm trying to find solution how to implement redirection from index for example to label.notes. One of methods described in documentation is:
App.IndexRoute = Ember.Route.extend({
redirect: function() {
this.transitionTo('label.notes', 0);
}
});
Here is jsbin with full example http://jsbin.com/UnasOse/1/edit
This works if user navigates by clicking links, but if manage opened by url, or page updated user will be redirected to notes.
So, how to implement redirection only then user opens root url (index)?
Using the your current router mapping, you have the routes index.manage and label.notes.
When the page is refreshed in the index.manage, first it will transition to the parent route, in that case the index, and after to manage. But in you index you have the redirect, so the manage isn't processed.
Just remove of your mapping the resource('index') and update your manage route to reflect the new configuration, so link-to index.manage will become manage, and data-template-name=index/manage to manage etc.
The updated route mapping is the following:
App.Router.map(function () {
// this.route('index', { path: '/' }); generated by ember
this.resource('label', { path: '/label' }, function() {
this.route('notes', { path: '/:label_id' });
});
this.route('manage', { path: '/manage' });
});
You can keep your IndexRoute, because ember create by default a this.route('index', { path: '/' }). So your IndexRoute will execute just when the user go to http://yoursite.com/
You can see that sample in action in this jsbin http://jsbin.com/ucanam/1024/edit

Loading data into root route of ember router when it's created outside of application.create()

When you want to use classes you created in Em.Application.create() in your router you need to specify the router outside of the application.create. But because the application is automatically initialized the router doesn't route to the / route.
You used to be able to defer the initialization by adding autoinit: false to the application.create. Now you are supposed to use App.deferReadiness() and App.advanceReadiness(). However this doesn't appear to work.
And I can't seem to escape the feeling that you are "supposed" to do it differently.
I added the minimal code to show the problem below. There is also a jsfiddle here
EDIT:
Apparently there is a new router in ember I kinda sorta overlooked that. I've changed the code to the new router, but guess what it still doesn't work :P
window.App = App = Em.Application.create({
ApplicationController: Em.Controller.extend({}),
ApplicationView: Em.View.extend({
template: Em.Handlebars.compile('{{outlet}}'),
}),
ExtendedPatientController: Em.ObjectController.extend({}),
ExtendedPatientView: Em.View.extend({
classNames: ['patient-view', 'extended'],
template: Em.Handlebars.compile('{{name}}')
}),
Patient: Em.Object.extend({
name: undefined,
}),
});
App.Router.map(function (match) {
match('/').to('application', function (match) {
match('/').to('extendedPatient');
})
});
App.deferReadiness();
App.ExtendedPatientRoute = Em.Route.extend({
setupController: function (controller) {
controller.set('', App.Patient.create({
name: "Bert"
}));
},
renderTemplates: function () {
this.render('extendedPatient', {
into: 'application'
});
}
});
App.advanceReadiness();
You're actually doing a lot more work than you need to here.
Here's all the code that you need to make your example work.
Template:
<script type="text/x-handlebars" data-template-name="index">
<div class="patient-view extended">
<p>Name: {{name}}</p>
</div>
</script>
App:
window.App = Em.Application.create();
App.Patient = Em.Object.extend({
name: null
});
App.IndexRoute = Em.Route.extend({
model: function() {
return App.Patient.create({
name: "Bert"
});
}
});
The working fiddle is at: http://jsfiddle.net/NXA2S/23/
Let me explain it a bit:
When you go to /, you are entering the automatic index route. All you need to do to show something on the screen for that route is to implement an index template. The easiest way to do that when you're getting up and running is to put your template in your index.html. Later, you will probably want to use build tools (see my answer here for more information).
You can control what model is displayed in a route's template by overriding the model hook in its route handler. In the case of index, the route handler is App.IndexRoute. In this case, the model is a brand new App.Patient.
You will probably want to implement controllers and events. You can learn more about the router on the Ember.js website
So the new router does solve this problem and does feel a bit shinier.
I finaly found out how to do this basic example this is what happens in the router:
App.Router.map(function (match) {
match('/').to('extendedPatient');
});
This what needs to happen in the views:
ExtendedPatientView: Em.View.extend({
classNames: ['patient-view', 'extended'],
//You need to specify the defaultTemplate because you extend the view class
//instead on initializing it.
defaultTemplate: Em.Handlebars.compile('{{name}}')
}),
You do not have to defer the readiness in the app the new router fixes that.
And in the route you do not need to specify the renderTemplates so the router now looks like:
App.ExtendedPatientRoute = Em.Route.extend({
setupController: function (controller) {
controller.set('content', App.Patient.create({
name: "Bert"
}));
},
});
http://jsfiddle.net/NXA2S/28/

Categories

Resources