Ember - Nothing handled the action occurs - ember.js

Nothing handled the action error occurs for the following code. How to resolve this?
I have created a view, an object for my sample app using ember. But the action part is not working.
How to bind an action to a view?
HTML:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Ember Starter Kit</title>
<link rel="stylesheet" href="css/normalize.css">
<link rel="stylesheet" href="css/style.css">
<link href="http://netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/css/bootstrap-combined.no-icons.min.css" rel="stylesheet">
</head>
<body>
<script type="text/x-handlebars">
<ul class="mod-choosable-list">
{{view Ember.CollectionView
contentBinding="App.teachersController"
itemViewClass="App.TeacherView"
tagName="div"
}}
</ul>
</script>
<script type="text/x-handlebars" data-template-name="teacher-view">
<div {{action 'refresh'}}><b>{{view.content.name}}</b></div>
</script>
<script src="js/libs/jquery-v1.11.1.js"></script>
<script src="js/libs/handlebars-v1.3.0.js"></script>
<script src="js/libs/ember-v1.6.1.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/showdown/0.3.1/showdown.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/moment.js/2.1.0/moment.min.js"></script>
<script src="js/app.js"></script>
</body>
</html>
JS:
App = Ember.Application.create({});
App.Teacher = Ember.ObjectController.extend({
id: null,
name: null,
students: null,
actions: {
refresh: function(){
alert("refresh");
}
}
});
App.TeacherView = Ember.View.extend({
templateName: 'teacher-view'
});
App.set('teachersController', Ember.ArrayController.create({
content: [
App.Teacher.create({id:1, name: "mr.katz", students: [2, 3]}),
App.Teacher.create({id:2, name: "mr.dale", students: [1]})
]
}));

When you trigger the action refresh, ember will look for the action in the controller. Since you have not specified a controller for the view, the controller for the application template will be used which is App.ApplicationController.
You can use the following code and your action will trigger.
App.ApplicationController = Em.Controller.extend({
actions: {
refresh: function(){
alert("refresh");
}
}
});
You can specify the actions in the view too. In that case you will need to specify the target for the action. This will tell ember where to look for the action handler.
App.TeacherView = Ember.View.extend({
templateName: 'teacher-view',
actions: {
refresh: function(){
alert("refresh");
}
}
});
<div {{action 'refresh' target="view"}}><b>{{view.content.name}}</b></div>
You can specify a controller for view on its init event.
App.TeacherView = Ember.View.extend({
templateName: 'teacher-view',
setup:function() {
this.set('controller', App.Teacher.create());
}.on('init')
});

Related

Making an ajax call and loading the string return by that call into a label in emberJS

I am new to EmberJs. I want to make an ajax call which returns a string. And once I get the data from the ajax call, I want to load the data into a label. Where can I find a simple example for same.
Here's a simple version of what you're asking:
//js
App = Ember.Application.create();
App.IndexView = Ember.View.extend({
didInsertElement: function() {
Em.run.later(function() {
$.getJSON('http://baconipsum.com/api/?callback=?', {
'type': 'meat-and-filler',
'start-with-lorem': '1',
'paras': '3'
},
function(baconGoodness) {
if (baconGoodness && baconGoodness.length > 0) {
$("#bacon").html('');
for (var i = 0; i < baconGoodness.length; i++)
$("#bacon").append('<p>' + baconGoodness[i] + '</p>');
$("#bacon").show();
}
});
}, 800)
}
});
/*css*/
html,
body {
margin: 20px;
}
<!-- html -->
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Ember Starter Kit</title>
<link rel="stylesheet" href="http://cdnjs.cloudflare.com/ajax/libs/normalize/2.1.0/normalize.css">
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script src="http://builds.handlebarsjs.com.s3.amazonaws.com/handlebars-v1.3.0.js"></script>
<script src="http://builds.emberjs.com/tags/v1.6.1/ember.js"></script>
</head>
<body>
<script type="text/x-handlebars">
<h2>Welcome to Ember.js</h2>
{{outlet}}
</script>
<script type="text/x-handlebars" data-template-name="index">
<div id="bacon">Loading bacon...</div>
</script>
</body>
</html>
As I have no clue what your application looks like, I'll just assume you have a view somewhere in your app that has a template with an html element with an id. If this is not your scenario.. that's fine, use the idea presented here and try to apply in your project.
For this sample, I created an index view with the following template:
<script type="text/x-handlebars" data-template-name="index">
<div id="bacon">Loading bacon...</div>
</script>
It only has a div called #bacon which I'm putting the response from some ajax request into.
Then in the IndexView class I added a handler for didInsertElement with an ajax request. This means that right after the Index view gets inserted into the DOM, it will fire this request.
App.IndexView = Ember.View.extend({
didInsertElement: function() {
Em.run.later(function() {
$.getJSON('http://baconipsum.com/api/?callback=?', {
'type':'meat-and-filler',
'start-with-lorem':'1',
'paras':'3'
},
function(baconGoodness) {
if (baconGoodness && baconGoodness.length > 0) {
$("#bacon").html('');
for (var i = 0; i < baconGoodness.length; i++) {
$("#bacon").append('<p>' + baconGoodness[i] + '</p>');
}
$("#bacon").show();
}
});
}, 800);
}
});
Another approach would be through the Route. You could have that ajax request in the model hook of your route, and then you can simply use handlebars expressions in your template. Something like this:
App = Ember.Application.create();
App.IndexRoute = Ember.Route.extend({
model: function() {
return $.getJSON('http://baconipsum.com/api/?callback=?', {
'type': 'meat-and-filler',
'start-with-lorem': '1',
'paras': '3'
});
}
});
html,
body {
margin: 20px;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Ember Starter Kit</title>
<link rel="stylesheet" href="http://cdnjs.cloudflare.com/ajax/libs/normalize/2.1.0/normalize.css">
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script src="http://builds.handlebarsjs.com.s3.amazonaws.com/handlebars-v1.3.0.js"></script>
<script src="http://builds.emberjs.com/tags/v1.6.1/ember.js"></script>
</head>
<body>
<script type="text/x-handlebars">
<h2>Welcome to Ember.js</h2>
{{outlet}}
</script>
<script type="text/x-handlebars" data-template-name="index">
<div>{{model}}</div>
</script>
</body>
</html>
That div doesn't need an id anymore, since we are using the controller's model property in the template:
<script type="text/x-handlebars" data-template-name="index">
<div>{{model}}</div>
</script>
Then the route implementation goes like this:
App.IndexRoute = Ember.Route.extend({
model: function() {
return $.getJSON(
'http://baconipsum.com/api/?callback=?', {
'type':'meat-and-filler',
'start-with-lorem':'1',
'paras':'3'
});
}
});
If this code doesn't apply to your scenario, try explaining it a little better. It really depends on what you are doing. Please follow the tutorials, read blogs, watch screen cats... keep your self up to date (not just ember).
This could have been done differently.. in many ways.. so it really depends on what you're doing.

Ember.js current link not marked as "active" when access by direct url visit from browser

I have the following minimal app.
Main container has a link to "Todos". When I click "Todos" link it gets a class active and becomes red by following the according css rule. When I submit #/todos url in my browser it loads the correct template with "Todos" link marked with class active.
The problem appears with the nested object links.
When I follow link to a specific todo it renders a todo template and marks the link red. But when I submit #/todos/1 url in my browser it responds with the correct template with the correct model (it shows the id), but link doesn't have a class active.
So my problem is that by submitting url #/todos/1 in browser the according link doesn't get a class active.
JSBin: http://jsbin.com/vopajaro/1#/todos/2
index.html
<!DOCTYPE html>
<html>
<head>
<script src="http://code.jquery.com/jquery-2.0.0.js"></script>
<script src="http://builds.handlebarsjs.com.s3.amazonaws.com/handlebars-1.0.0.js"></script>
<script src="http://builds.emberjs.com/tags/v1.3.0/ember.js"></script>
<script src="app.js"></script>
<link rel="stylesheet" href="app.css"/>
</head>
<body>
<script type="text/x-handlebars" data-template-name="application">
{{#link-to "todos"}}Todos{{/link-to}}
{{outlet}}
</script>
<script type="text/x-handlebars" data-template-name="todos">
{{#each}}
{{#link-to "todo" this}}{{id}}{{/link-to}}
{{/each}}
{{outlet}}
</script>
<script type="text/x-handlebars" data-template-name="todo">
{{id}}
</script>
</body>
</html>
app.js
var App = Ember.Application.create();
App.Router.map(function() {
this.resource('todos', function() {
this.resource('todo', { path: ":id" });
});
});
App.TodosRoute = Ember.Route.extend({
model: function() {
return [{id: 1, name: 'todo 1'}, {id: 2, name: 'todo 2'}];
}
});
app.css
a.active {
color: red;
}

Parse Ember fixture data and make available to nested view

I am trying to feed fixture data to both a handlebars template and a nested view. With my current setup, the data reaches my handlebars template just fine, but not the view. I suspect I am missing some basic piece of the ember.js puzzle. Would someone please advise me?
I've asked a question about a setup that is similar but uses ajax instead of fixture data, but have further simplified my setup in the hopes of getting some direction.
Thank you!
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Ember Starter Kit</title>
<link rel="stylesheet" href="css/normalize.css">
<link rel="stylesheet" href="css/leaflet.css">
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<script type="text/x-handlebars">
{{outlet}}
</script>
<script type="text/x-handlebars" id="index">
{{view App.MapView id="map" contentBinding="this"}}
<div id="blog">
<ul>
{{#each}}
<li>{{title}}</li>
{{/each}}
</ul>
</div>
</script>
<script src="js/libs/jquery-1.10.2.js"></script>
<script src="js/libs/handlebars-1.1.2.js"></script>
<script src="js/libs/ember-1.5.0.js"></script>
<script src="js/libs/ember-data.js"></script>
<script src="js/libs/leaflet-src.js"></script>
<script src="js/app.js"></script>
</body>
</html>
window.App = Ember.Application.create();
App.ApplicationAdapter = DS.FixtureAdapter.extend();
App.Router.map(function() {
this.resource('index', { path: '/' });
});
App.IndexRoute = Ember.Route.extend({
model: function () {
return this.store.find('storyPrev');
}
});
App.StoryPrev = DS.Model.extend({
title: DS.attr('string')
});
App.StoryPrev.FIXTURES = [
{
id: 1,
title: 'You Better Believe This!',
coordinates: [-73.989321, 40.6778]
},
{
id: 2,
title: 'Holy Crap, Unreal!',
coordinates: [-73.989321, 40.6779]
},
{
id: 3,
title: 'Big Bucks Made E-Z!',
coordinates: [-73.989321, 40.6780]
}
];
App.MapView = Ember.View.extend({
didInsertElement: function () {
var map = L.map('map', {zoomControl: false}).setView([40.685259, -73.977664], 14);
L.tileLayer('http://{s}.tile.cloudmade.com/[redacted key]/[redacted id]/256/{z}/{x}/{y}.png').addTo(map);
L.marker([40.685259, -73.977664]).addTo(map);
console.log(this.get('content'));
//THIS IS WHERE I GET STUCK
}
});
The view is backed by a controller, so you would do this.get('controller') to get the controller which is backed by your collection which if you wanted to get the collection (which isn't necessary since you can iterate the controller) you could do this.get('controller.model').
var controller = this.get('controller');
controller.forEach(function(item){
console.log(item.get('title'));
});
http://emberjs.jsbin.com/OxIDiVU/373/edit

add observer on a function ember.js

my english isn't very good, apologise in advice
i'm working whit ember.js and i would like that the ac function run when the components/graph-pie render. i know that i need to put an observer and i read the documentation, but i don't understand where and how put the observer.
this is the code
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>COMPONENT</title>
<script src="js/libs/jquery-1.10.2.js"></script>
<script src="js/libs/handlebars-1.1.2.js"></script>
<script src="js/libs/ember-1.2.0.js"></script>
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script src="js/app.js"></script>
<link rel="stylesheet" href="css/normalize.css">
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<script type="text/x-handlebars">
<div>prova<div>
<button> {{#link-to "graphs"}}graph{{/link-to}}</button>
{{outlet}}
</script>
<script type="text/x-handlebars" data-template-name="graphs">
{{graph-pie}}
</script>
<script type ="text/x-handlebars" id="graphs" data-template-name="components/graph-pie">
<div id="BC">
<div id="Gphic">
</div>
</div>
</script>
</body>
</html>
app.js
App = Ember.Application.create();
App.Router.map (function (){
this.route("graphs");
});
App.GraphsRoute = Ember.Route.extend ({
model: function() {
return data;
}
});
App.GraphPieComponent = Ember.Component.extend({
actions: {
ac: function () {
//do something
}
}
})
App.GraphsController = Ember.ArrayController.extend({
});
var data= ...
You can use the didInsertElement hook
http://emberjs.com/api/classes/Ember.Component.html#event_didInsertElement
Which ember fires after the component is inserted
You could the put your code inside the hook, or call your AC method from within.
You will want to use the didInsertElement event on the component, something like this.
App.GraphPieComponent = Ember.Component.extend({
didInsertElement: function() {
this._ac();
},
_ac: function() {
//do something
},
actions: {
ac: function () {
this._ac();
}
}
});

Ember Data Beta 2 FixtureAdapter Errors

I'm assuming that the API has changed for how to use adapters but I couldn't find any examples using the fixture adapter. I'm using the new injected store but not sure how to interact with it. I'm just trying to fetch all of the data. Here is a fiddle http://emberjs.jsbin.com/ESoduyA/1/edit.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Ember Starter Kit</title>
<link rel="stylesheet" href="https://rawgithub.com/emberjs/starter-kit/v1.0.0/css/normalize.css">
</head>
<body>
<script type="text/x-handlebars">
<h2>Welcome to Ember.js</h2>
{{outlet}}
</script>
<script type="text/x-handlebars" data-template-name="index">
<ul>
{{#each item in model}}
<li>{{item.type}}</li>
{{/each}}
</ul>
</script>
<script src="https://rawgithub.com/emberjs/starter-kit/v1.0.0/js/libs/jquery-1.9.1.js"></script>
<script src="https://rawgithub.com/emberjs/starter-kit/v1.0.0/js/libs/handlebars-1.0.0.js"></script>
<script src="https://rawgithub.com/emberjs/starter-kit/v1.0.0/js/libs/ember-1.0.0.js"></script>
<script src="http://builds.emberjs.com/beta/ember-data.js"></script>
</body>
</html>
JS
App = Ember.Application.create();
App.Router.map(function() {
// put your routes here
});
App.IndexRoute = Ember.Route.extend({
model: function() {
return this.get('store').findAll('color');
}
});
App.store = DS.Store.create({
adapter: 'DS.FixtureAdapter'
});
App.Color = DS.Model.extend({
type: DS.attr()
});
App.Color.FIXTURES = [
{type: 'blue'},
{type: 'green'}
];
This results in these errors.
Assertion failed: No model was found for 'html' ember-1.0.0.js:394
DEPRECATION: Action handlers contained in an `events` object are deprecated in favor of putting them in an `actions` object (error on <Ember.Route:ember245>)
at Object.triggerEvent (https://rawgithub.com/emberjs/starter-kit/v1.0.0/js/libs/ember-1.0.0.js:30519:13)
at trigger (https://rawgithub.com/emberjs/starter-kit/v1.0.0/js/libs/ember-1.0.0.js:29641:16)
at handleError (https://rawgithub.com/emberjs/starter-kit/v1.0.0/js/libs/ember-1.0.0.js:29903:9)
at invokeCallback (https://rawgithub.com/emberjs/starter-kit/v1.0.0/js/libs/ember-1.0.0.js:8055:19)
at null.<anonymous> (https://rawgithub.com/emberjs/starter-kit/v1.0.0/js/libs/ember-1.0.0.js:8109:11)
at EventTarget.trigger (https://rawgithub.com/emberjs/starter-kit/v1.0.0/js/libs/ember-1.0.0.js:7878:22)
at https://rawgithub.com/emberjs/starter-kit/v1.0.0/js/libs/ember-1.0.0.js:8180:17
at Object.DeferredActionQueues.flush (https://rawgithub.com/emberjs/starter-kit/v1.0.0/js/libs/ember-1.0.0.js:5459:24)
at Object.Backburner.end (https://rawgithub.com/emberjs/starter-kit/v1.0.0/js/libs/ember-1.0.0.js:5545:27) ember-1.0.0.js:394
Error while loading route:
TypeError
ember-1.0.0.js:394
Uncaught TypeError: Cannot set property 'store' of undefined
Here's some info on the FixtureAdapter. http://emberjs.com/guides/getting-started/using-fixtures/
tl,dr :
App.ApplicationAdapter = DS.FixtureAdapter.extend();
App.Color.FIXTURES = [
{id: 1, type: 'blue'},
{id: 2, type: 'green'}
];
Tweaked bin : http://emberjs.jsbin.com/ESoduyA/4/edit