add observer on a function ember.js - 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();
}
}
});

Related

Ember - Nothing handled the action occurs

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')
});

Ember - Missing helper action for HBS files

I have written a html with a div.
I have two hbs files. I rendered one as partial and other as normal. I am not able to invoke action on the templates. I am getting missing helper error.
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">
</head>
<body>
<div id="holder">
</div>
<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="js/libs/ember-data.js"></script>
<script src="js/app.js"></script>
</body>
</html>
JS:
var data={title: "My New Post", body: "This is my first post!"};
function getTemplate(templateName,hbsPath,type){
$.ajax({
url: hbsPath, //ex. js/templates/mytemplate.handlebars
cache: true
}).done(function (src) {
if (type === "partial") {
Handlebars.registerPartial(templateName, $(src).html());
} else {
template = Handlebars.compile($(src).html());
temp=template(data);
$("#holder").append(temp);
}
});
}
getTemplate("dummy","/Test/templates/dummy.hbs","partial");
getTemplate("dummy","/Test/templates/application.hbs");
App = Ember.Application.create({});
App.Router.map(function(){
this.resource('dummy');
});
App.ApplicationController=Ember.ObjectController.extend({
needs:['dummy'],
actions:{
refresh: function(){
alert("application template refresh");
}
}
});
App.DummyController=Ember.ObjectController.extend({
actions:{
refresh: function(){
alert("dummy template refresh");
}
}
});
HBS:
application.hbs:
<script id="application" type="text/x-handlebars-template">
{{> dummy}}
</script>
dummy.hbs:
<script type="text/x-handlebars" data-template-name='dummy'>
<div {{action 'refresh' target="controllers.dummy"}}>
Refresh
</div>
<div {{action 'refresh'}}>
Refresh
</div>
</script>
The code in ur demo and the code in question are different. Here is a fixed demo based on the code in ur question.
Fixing the demo u provide may need you to include the vanilla handlebars library as ember is now using HTMLBars which is built on top of handlebars but a bit different.
Em.Handlebars.compile is now actually using HTMLBars compile method. You can see here.
You may need to use something like https://github.com/rwjblue/broccoli-ember-inline-template-compiler

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.

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

Beginners query in Emberjs

//index.html
<html>
<head>
<title>An Ember dice roller</title>
</head>
<body>
<script type="text/javascript" src="C:/Users/Guest/Downloads/ember/starter-kit-1.0.0/js/libs/jquery-1.9.1.js"></script>
<script type="text/javascript" src="C:/Users/Guest/Downloads/ember/starter-kit-1.0.0/js/libs/handlebars-1.0.0.js"></script>
<script type="text/javascript" src="C:/Users/Guest/Downloads/ember/starter-kit-1.0.0/js/libs/ember-1.0.0.js"></script>
<script type="text/javascript" src="C:/Users/Guest/Downloads/ember/starter-kit-1.0.0/js/app.js"></script>
<script type="text/x-handlebars" >
<h1>Dice Roller</h1>
{{#link-to 'roll'}}Click here{{/link-to}}
{{#link-to 'index'}}Go to index{{/link-to}}
{{outlet}}
</script>
<script type="text/x-handlebars" id="roll">
Hi!
</script>
<script type="text/x-handlebars" id="index">
<p>
Our content goes here
</p>
</script>
</body>
</html>
//app.js
var Roller = Ember.Application.create({
LOG_TRANSITIONS: true,
LOG_BINDINGS: true,
LOG_VIEW_LOOKUPS: true,
LOG_STACKTRACE_ON_DEPRECATION: true,
LOG_VERSION: true,
debugMode: true
});
Roller.Router.map(function () {
this.resource('index');
this.resource('roll');
});
What is wrong with this code?
I am getting the following error. My index.html page doesn't load anything.
I am beginner for ember.js.Can anyone please help me?
Assertion failed: The URL '/' did match any routes in your application
By default ember create something like this:
Roller.Router.map(function () {
this.route('index', { path: '/' });
});
But your router is overriding the index route with this:
this.resource('index');
So to be able to render the index template you will need to access your app with http://yourhost/#/index intead of http://yourhost/.
If you update your router mapping, and remove the this.resource('index') all will works:
Roller.Router.map(function () {
this.resource('roll');
});
This is a updated jsbin with this working http://jsbin.com/ucanam/1499/edit