Emberjs rootElement - ember.js

In guide I can find:
"
If you are embedding an Ember application into an existing site, you can have event listeners set up for a specific element by providing a rootElement property:
window.App = Ember.Application.create({
rootElement: '#sidebar'
});
"
Please give me example how to use it corretly.

HTML
<script type="text/x-handlebars" data-template-name="app-view">
My ember app view
</script>
This is a static content
<div id="app-container"></div>
This is a static content
JS
App = Ember.Application.create({
rootElement: '#app-container'
});
App.ApplicationController = Ember.Controller.extend();
App.ApplicationView = Ember.View.extend({
templateName: 'app-view'
});
App.Router = Ember.Router.extend({
root: Ember.Route.extend({
index: Ember.Route.extend({
route: '/',
connectOutlets: function (router) {
// do some stuff here...
}
})
})
});
App.initialize();
Here is the JSFiddle: http://jsfiddle.net/MikeAski/xtzNB/

Related

FirebaseAdapter not recognized on my Ember app

I'm trying to use Firebase with my Ember app. I installed Emberfire but my app returns
Uncaught TypeError: Cannot read property 'extend' of undefined
Because it doesn't read 'FirebaseAdapter'
App.ApplicationAdapter = DS.FirebaseAdapter.extend({
firebase: new Firebase('https://glowing-fire-number.firebaseio.com/')
});
I checked if Ember data is being loaded before Firebase and EmberFire too. Here are my script references:
<!-- script references -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.2/jquery.min.js"></script>
<script src="js/bootstrap.min.js"></script>
<script src="http://maps.googleapis.com/maps/api/js?sensor=false&extension=.js&output=embed"></script>
<script src="js/scripts.js"></script>
<script src="js/libs/jquery-1.11.2.min.js"></script>
<script src="js/libs/handlebars-v1.3.0.js"></script>
<script src="js/libs/ember.js"></script>
<script src="js/libs/moment.js"></script>
<script src="http://builds.emberjs.com/tags/v1.0.0-beta.12/ember-data.js"></script>
<script src="js/app.js"></script>
<script src="vendor/list-view.js"></script>
<script src="js/controller.js"></script>
<script src="https://cdn.firebase.com/js/client/2.2.2/firebase.js"></script>
<script src="https://cdn.firebase.com/libs/emberfire/1.3.3/emberfire.min.js"></script>
And my App.js
App = Ember.Application.create();
App.Router.map(function() {
// put your routes here
this.resource('stacks')
this.resource('stack', {path: ':stack_id'}, function() {
this.route('edit');
});
this.route('create');
});
App.IndexRoute = Ember.Route.extend({
beforeModel: function() {
this.transitionTo('stacks');
}
});
App.StacksRoute = Ember.Route.extend({
model: function() {
return this.store.findAll('stack');
}
});
App.StackRoute = Ember.Route.extend({
model: function(params) {
return stacks.findBy('id', params.stack_id);
}
});
Ember.Handlebars.helper('format-date', function(date) {
return moment(date).fromNow();
});
App.CreateRoute = Ember.Route.extend({
});
//EmberFire stuff
App.ApplicationAdapter = DS.FirebaseAdapter.extend({
firebase: new Firebase('https://glowing-fire-2514.firebaseio.com/')
});
App.Stack = DS.Model.extend({
title: DS.attr('string'),
location: DS.attr('string'),
date: DS.attr('number'),
details: DS.attr('string')
});
Any idea? I appreciate your help!
It looks like you need to include app.js after you include EmberFire. There's also a missing semicolon in your router after this.resource('stacks') but I don't think that's causing the error.
We just released some updates that make it much easier to use EmberFire as an ember-cli addon, I'd recommend checking it out. Details are here: https://www.firebase.com/blog/2015-03-09-new-emberfire-features.html

Filling Ember selection with data received from server

I would like to receive json data from server and then generate html selection tag in Ember. This is my handlebars template:
<script type="text/x-handlebars" data-template-name="application">
{{outlet}}
</script>
<script type="text/x-handlebars" data-template-name="rankings">
{{view Ember.Select contentBinding="countries" optionLabelPath="countries.name" optionValuePath="countries.path"}}
</script>
and my Ember trunk
App.ApplicationAdapter = DS.RESTAdapter;
App.Router.map(function() {
this.route('rankings')
});
App.RankingsRoute = Ember.Route.extend({
setupController: function(controller, model) {
controller.set('countries', this.store.findAll('country'));
}
});
App.RankingsController = Ember.Controller.extend({
countries: []
});
App.Country = DS.Model.extend({
path: DS.attr('string'),
name: DS.attr('string'),
}
It is not working fine. I am not having any errors in console and template is not rendering with this route and controller. What can be wrong?
Ember.Select looks for data on your controller's model. You have the countries array set up outside of your content, so it will not be able to view the data.
Personally, I would do it in the following way, though there are a couple of different approaches you can take to get similar results:
App.ApplicationAdapter = DS.RESTAdapter;
App.Router.map(function() {
this.route('rankings')
});
App.RankingsRoute = Ember.Route.extend({
model: function() {
return {countries : this.store.findAll('country')};
}
});
App.RankingsController = Ember.Controller.extend({
});
App.Country = DS.Model.extend({
path: DS.attr('string'),
name: DS.attr('string'),
}

Emberjs Application Routes and Controllers

Can someone explain why this works:
Code in App.js:
App.ApplicationRoute = Ember.Route.extend({
setupController : function (params) {
this.controllerFor('food').set('model', App.Food.find(params.food_id));
}
});
But the following won't, unless I explicitly declare App.FoodController = Ember.ObjectController.extend();
App.FoodRoute = Ember.Route.extend({
model : function(params) {
return App.Food.find(params.food_id);
}
});
This is the code I'm using in index.html and does not change between blocks of code
<script type="text/x-handlebars" data-template-name="application">
{{ outlet }}
</script>
<script type="text/x-handlebars" data-template-name="food">
{{name}}
</script>
Router:
App.Router.map(function() {
this.resource( 'foods' );
this.resource( 'food', { path : '/food/:food_id' } );
});
The code that you have shown seems OK. Here is a working fiddle that proves it:
http://jsfiddle.net/ebXeS/2/
The only thing wrong about the code is this part (which is excluded from the fiddle):
App.ApplicationRoute = Ember.Route.extend({
setupController : function (params) {
this.controllerFor('food').set('model', App.Food.find(params.food_id));
}
});
According to your Router definition, you should not have food_id in the parameters of your application route. More than that, you should access the controller for the food route in the uhm... FoodRoute. Read more about Ember and the way it does routing (http://emberjs.com/guides/).

Ember's Router for pre4

I'm trying to work with Ember's pre4 release, but I'm getting stuck on the Router.
I get an error that says Uncaught TypeError: Cannot Call method 'map' of undefined.
Relavent code:
App.Router.map(function() {
this.route("about", { path: "/about" });
this.route("favorites", { path: "/favs" });
});
Relative documentation.
I've loaded Ember.js and jQuery. Ember pre4 also throws an error: Uncaught TypeError: Object prototype may only be an Object or null.
Am I doing something wrong? Are the guides just not updated?
The code I have so far:
window.App = Ember.Application.create({
ApplicationView: Ember.View.extend({
templateName: 'application'
}),
ApplicationController: Ember.Controller.extend({
}),
SiteView: Em.View.extend({
templateName: 'site-template'
}),
SiteController: Em.ArrayController.extend(),
});
App.Router.map(function() {
this.route("about", { path: "/about" });
this.route("favorites", { path: "/favs" });
});
I'm not seeing anything wrong with the code you posted. Was able to run it in jsbin, and after adding "site" as the default route the app appears to be working.
App = Ember.Application.create({
ApplicationView: Ember.View.extend({
templateName: 'application'
}),
ApplicationController: Ember.Controller.extend({
}),
SiteView: Em.View.extend({
templateName: 'site-template'
}),
SiteController: Em.ArrayController.extend()
});
App.Router.map(function() {
this.route("site", { path: "/" });
this.route("about", { path: "/about" });
this.route("favorites", { path: "/favs" });
});
<script type="text/x-handlebars" data-template-name="site-template">
This is the site template
</script>
<script type="text/x-handlebars">
This is the application template
{{outlet}}
</script>
See jsbin for working copy.
My best guess is that your errors are coming from some either an incompatible version of jQuery or because you don't have handlebars.js - both are required to run ember. Also, in development be sure to use ember-1.0.0-pre.4.js! instead of ember-1.0.0-pre.4.min.js. The minimized version is optimized for production use so does not include helpful debug messages that will make it easier to spot these kind of problems.

How to route to the same nested state but have a different context?

I currently struggle to get a nested route to work, where one of the path elements is dynamic. That's the scenario I want to achieve:
The page contains the description of a project. Within the page is a tab menu to select different views. That should reflect in the URL as well. So I want to have different urls like:
url#/project1/info
url#/project1/status
url#/project1/...
To not repeat the :project parameter I added a nested project route that is not a leaf but only responsible for serialization/deserialization of the project itself.
Everything works fine as long as I use the initial project. But it can happen, that I want to link from one project to another project. That means the URL should change from url#/project1/info -> url#/project2/info and thus the view should change as well to display the infos about project2.
Sounds straightforward. However the deserialization method of the project route is not called when I link to project2 with an action helper
<a {{action changeProject context="App.project2" href=true}}>Go to project 2</a>
I guess that is because I am already in the info state. However how do I then propagate the context change? A simplified case you can find in the fiddle http://jsfiddle.net/jocsch/HYbZj/30/ or view it directly http://jsfiddle.net/jocsch/HYbZj/30/show/#/project1/info
Router: Ember.Router.extend({
enableLogging: true,
root: Ember.Route.extend({
changeProject: Em.State.transitionTo('project.info'),
index: Ember.Route.extend({
route: '/',
}),
project: Ember.Route.extend({
route: '/:project',
deserialize: function(router, params) {
var proj = App.get(params['project']);
router.get("applicationController").set("content", proj);
return proj;
},
serialize: function(router, context) {
return {project: context.id};
},
index: Ember.Route.extend({
route: '/',
redirectsTo: 'info'
}),
info: Ember.Route.extend({
route: '/info',
connectOutlets: function(router) {
var ctrl = router.get('applicationController');
ctrl.connectOutlet('project', ctrl.get('content'));
}
})
})
})
})
You do not need any custom serialization/deserialization.
One important missing thing in your code is the context passing in changeProject handler.
I would write the whole thing as follow:
JS
App = Ember.Application.create();
App.Project = DS.Model.extend({
name: DS.attr('string'),
description: DS.attr('string')
});
App.Project.FIXTURES = [{
id: '36',
name: 'First project',
description: 'My very first project'
}, {
id: '42',
name: 'Another project',
description: 'My other favorite project'
}];
App.store = DS.Store.create({
adapter: DS.fixtureAdapter,
revision: 4
});
App.ApplicationController = Ember.Controller.extend();
App.ApplicationView = Ember.View.extend({
templateName: 'app-view'
})
App.ProjectsController = Ember.ArrayController.extend();
App.ProjectsView = Ember.View.extend({
templateName: 'projects-view'
})
App.ProjectController = Ember.ObjectController.extend();
App.ProjectView = Ember.View.extend({
templateName: 'project-view'
})
App.InfoController = Ember.ObjectController.extend();
App.InfoView = Ember.View.extend({
templateName: 'info-view'
})
App.Router = Ember.Router.extend({
enableLogging: true,
root: Ember.Route.extend({
index: Ember.Route.extend({
route: '/'
}),
showProjects: function(router) {
router.transitionTo('projects.index');
},
projects: Ember.Route.extend({
route: 'projects',
connectOutlets: function(router) {
var applicationController = router.get('applicationController');
applicationController.connectOutlet({
outletName: 'projectsList',
name: 'projects',
context: App.Project.find()
});
},
index: Ember.Route.extend({
route: '/'
}),
showProject: function(router, event) {
var project = event.context;
router.transitionTo('project.info', project);
},
project: Ember.Route.extend({
route: '/:project_id',
modelClass: 'App.Project',
connectOutlets: function(router, project) {
var applicationController = router.get('applicationController');
applicationController.connectOutlet('project', project);
},
info: Ember.Route.extend({
route: 'info',
connectOutlets: function(router) {
var projectController = router.get('projectController'),
project = projectController.get('content');
projectController.connectOutlet('info', project);
}
})
})
})
})
});
App.initialize();
Handlebars
<script type="text/x-handlebars" data-template-name='app-view'>
<h1>Welcome to projects app!</h1>
<a {{action showProjects}}>Projects home</a>
<hr/>
{{outlet projectsList}}
<hr/>
{{outlet}}
</script>
<script type="text/x-handlebars" data-template-name='projects-view'>
{{controller.length}} projects:
<ul>
{{#each project in controller}}
<li>
<a {{action showProject context="project"}}>{{project.name}}</a>
</li>
{{/each}}
</ul>
</script>
<script type="text/x-handlebars" data-template-name='project-view'>
<h2>Showing project <i>{{name}}</i></h2>
{{outlet}}
</script>
<script type="text/x-handlebars" data-template-name='info-view'>
{{description}}
</script>
JSFiddle # http://jsfiddle.net/MikeAski/fRea6/