[]I am trying to feed data (via an ajax call to a json file) to both a handlebars template and a leaflet map. With my current setup, the data reaches my handlebars template just fine, but doesn't render the coordinates data to the leaflet map. I suspect I am missing some basic piece of the ember.js puzzle. Would someone please advise me?
HTML/Handlebars Templates:
<!doctype html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no, minimal-ui">
<title>sbk_3.0.8</title>
<link rel="stylesheet" href="css/leaflet.css">
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<script type="text/x-handlebars" data-template-name="application">
{{outlet}}
</script>
<script type="text/x-handlebars" data-template-name="index">
{{view App.MapView id="map" contentBinding="this"}}
<div id="blog">
<ul>
{{#each item in model}}
<li>{{item.headline}}</li>
{{/each}}
</ul>
</div>
</script>
<!--DEPENDENCIES-->
<script src="js/libs/jquery-1.10.2.min.js"></script>
<script src="js/libs/handlebars-1.0.0.js"></script>
<script src="js/libs/ember.js"></script>
<!--MAP-->
<script src="js/libs/leaflet-src.js"></script>
<script src="js/libs/ember-leaflet.min.js"></script>
<!--APP-->
<script src="js/application.js"></script>
</body>
</html>
Ember:
App = Ember.Application.create();
App.Router.map(function() {
// put your routes here
});
App.IndexRoute = Ember.Route.extend({
model: function(){
return App.Item.all();
}
});
App.Item = Ember.Object.extend();
App.Item.reopenClass({
all: function() {
return $.getJSON("js/data/test_e.json").then(function(response) {
var items = [];
response.features.forEach( function (data) {
items.push( App.Item.create(data) );
});
return items;
});
}
});
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);
console.log(this.get('content'));
//HERE IS WHERE I GET STUCK. I CAN OUTPUT THE JSON TO THE CONSOLE...
//BUT HOW DO I DRILL DOWN, AND ULTIMATELY...
//HOW DO I SEND THE VALUE OF THE "CENTER" KEY TO LEAFLET, i.e. L.Marker([jsonObject.center]).addTo(map);
}
});
App.IndexController =
Ember.Controller.extend({});
JSON:
{
"features": [
{
"headline": "Docker, the Linux container runtime: now open-source",
"center" : [40.685259, -73.977664]
},
{
"headline": "What's Actually Wrong with Yahoo's Purchase of Summly",
"center" : [40.685259, -73.977664]
}
]
}
This is the same answer as the other question,
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
Related
I have a single-page AngularJS app.
The index.html file looks like this:
<html ng-app="myApp" ng-controller="MyCtrl as myctrl">
<head>
<link rel="stylesheet" href="my-style-sheet.css">
<title>{{myctrl.title}}</title>
</head>
<body>
<div class="container">
<ol>
<li><a ui-sref="stateA">StateA</a></li>
<li><a ui-sref="stateB">StateB</a></li>
</ol>
<div ui-view></div>
</div>
<script src="my-app.js"></script>
</body>
</html>
As the user clicks on the StateA or StateB links, the page displays the content of those pages in place of <div ui-view></div>. Terrific.
As the user clicks around, the displayed content changes. I need the title of the page to change too. Currently it gets the title from the controller MyCtrl like this: <title>{{myctrl.title}}</title>. But when the user clicks those links, those states each have their own controllers. So I cannot use <title>{{myctrl.title}}</title>.
How can I update the title when various states the user clicks on have different controllers?
You can attach some data to each state of your routes, like a value that can be used to set the title of the page.
.state('test', {
url: '/test',
templateUrl: '/templates/test.html',
data: {
title: 'test title'
}
})
Then write a directive to read the title. You can check to see if the required data is available on the state you are going to, and attach the whole thing to $stateChangeSuccess event.
function dynamicTitle($rootScope, $timeout) {
return {
link: function(scope, el) {
$rootScope.$on('$stateChangeSuccess', function(event, toState) {
var title = (toState.data && toState.data.title)
? toState.data.title
: 'Default title';
$timeout(function() {
el.text(title);
}, 0, false);
};);
}
};
}
angular.module('myApp').directive('dynamicTitle', dynamicTitle);
And attach it to your <title>
<title dynamic-title></title>
You can create an AngularJS factory, inject it, modify it by calling 'Title.setTitle()' from controllers
<html ng-app="app" ng-controller="Ctrl">
<head>
<title>{{ Title.title() }}</title>
app.factory('Title', function() {
var title = 'Hello';
return {
title: function() { return title; },
setTitle: function(newTitle) { title = newTitle }
};
});
I have 2 drop downs where selection of first drop down effects the data content of the second drop down.
The problem I have is this functionality is occurring only on first click instead it should happen every time.
Here is my jsFiddle with my working code and here is my code on jsbin(jsbin gives some error which I am unable to understand, help appreciated here too, #newbieTorture).
Thanks in Advance :)
App = Ember.Application.create();
App.Router.map(function() {
// put your routes here
});
App.ArticleAdapter= DS.FixtureAdapter.extend({});
App.Article =DS.Model.extend({
title: DS.attr(),
body: DS.attr(),
shouldReloadAll:true,
comments: DS.hasMany('comment', {async : true})
//async tells compiler to load data from comment everytime this is rendered
});
App.Comment =DS.Model.extend({
text: DS.attr(),
shouldReloadAll:true,
article: DS.belongsTo('article', { async: true })
});
App.Article.FIXTURES=[
{
id:1,
title : 'Ember',
body:'Its a great technology but need lot of studying and practice',
comments:[1]
},{
id:2,
title : 'Angular',
body:'it takes less understanding but has more coding the ember',
comments:[2,3]
//this will be an aray coz it is has many relation
}
];
App.Comment.FIXTURES=[
{
id:1,
text : 'Yyyieee excited to learn ember',
aricle: 1
//its not an array coz it will be related to single object
},{
id:2,
text : 'I will start Angular once i have fininshed with ember',
article: 2
},{
id:3,
text : 'Angular can be interesting',
article: 2
}
];
App.CommentAdapter= DS.FixtureAdapter.extend();
App.IndexController = Ember.ArrayController.extend({
articleValue: null,
selected: null,
articleStore: Em.computed(function(){
console.log("data is : " + this.get('articleValue'));
console.log("data is : " + this.get('selected'));
return this.store.findAll("article");
}).property("selected"),
availableComment: Em.computed(function () {
var make = this.get('selected');
// the line below returns the id and not an object
console.log(make);
if (make === undefined || make === null)
return [];
return this.get('selected').get('comments');
}).property('articleValue'),
actions:{
callIndexController: function(){
var select= this.get("selected");
console.log("hi :" + select);
}
}
});
App.IndexRoute = Ember.Route.extend({
model: function() {
return [];
},
});
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Ember Starter Kit</title>
</head>
<body>
<script type="text/x-handlebars">
<h2>Welcome to Ember.js</h2>
{{outlet}}
</script>
<script type="text/x-handlebars" id="index">
First drop down:
{{
view "select"
contentBinding=articleStore
optionLabelPath="content.title"
optionValuePath="content.id"
prompt="Pick a person:"
shouldReloadAll=true
selectionBinding=selected
valueBinding=articleValue
}}
<br>
<br>
Second drop down:
{{
view "select"
contentBinding=availableComment
optionLabelPath="content.text"
optionValuePath="content.id"
prompt="related task:"
shouldReloadAll=true
valueBinding=articleValue
}}
</script>
<script src="https://code.jquery.com/jquery-1.10.2.js"></script>
<script src="http://builds.emberjs.com/tags/v1.13.7/ember-template-compiler.js"></script>
<script src="http://builds.emberjs.com/tags/v1.13.7/ember.debug.js"></script>
<script src="http://builds.emberjs.com/tags/v1.13.7/ember-data.js"></script>
<script src="js/amit_dropdown.js"></script>
<!-- to activate the test runner, add the "?test" query string parameter -->
<script src="tests/runner.js"></script>
</body>
</html>
I am very new to AngularJS, and I am trying to get some items in JSON from a webservice I quickly made using ServiceStack. When I try the URL in the browser I can see the JSON object, but for some reason AngularJS fails to successfully get the data. Here's my implementation:
angular.module('SomeApp', []).controller('ItemsFetcher', [ '$http', function($http){
var x = this;
x.products= [
{
Name: 'Missing items',
Description: 'Could not access server'
}];
$http.get('http://localhost:29029/json/reply/GetAllItemsRequest')
.then(function(data){
x.products = [
{
Name: 'Success',
Description: 'Great stuff!'
}];
});
}]);
Here's the view:
<html ng-app="SomeApp">
<head>
<title>My First App</title>
<script type="text/javascript" src="angular.min.js"></script>
<script type="text/javascript" src="app.js"></script>
</head>
<body ng-controller="ItemsFetcher as fetcher">
<h3>PRODUCTS</h3>
<div ng-repeat="item in fetcher.products">
<div>{{item.Name}} - {{item.Description}}</div>
</div>
</body>
As I said, if I call http://localhost:29029/json/reply/GetAllItemsRequest in a browser, I can the JSON object.
Am I missing something ? Any ideas why this does not work ?
In case anyone could benefit from this, I had to either enable CORS (http://en.wikipedia.org/wiki/Cross-origin_resource_sharing) or to host both the webservice and website in the same place.
I am new to ember and ember-leaflet.js. I am trying to feed data (via an ajax call to a json file) to both my handlebars template and my ember-leaflet map. With my current setup, the data reaches my handlebars template just fine, but doesn't render the coordinates data to the ember-leaflet map.
I am using the two examples listed below as my guides, but have hit a wall because of my lack of experience with ember. Can anyone point me in the right direction please?
Ajax and ember example
Partial example of what I'm trying to accomplish
Handlebars template:
<script type="text/x-handlebars" data-template-name="application">
{{outlet}}
</script>
<script type="text/x-handlebars" data-template-name="index">
{{view App.MapView id="map"}}
<div id="blog">
<ul>
{{#each item in model}}
<li>{{item.headline}}</li>
{{/each}}
</ul>
</div>
</script>
Ember:
App = Ember.Application.create();
App.Router.map(function() {
// put your routes here
});
App.IndexRoute = Ember.Route.extend({
model: function(){
return App.Item.all();
}
});
App.Item = Ember.Object.extend();
App.Item.reopenClass({
all: function() {
return $.getJSON("js/data/test_e.json").then(function(response) {
var items = [];
response.features.forEach( function (data) {
items.push( App.Item.create(data) );
});
return items;
});
}
});
App.MarkerCollectionLayer =
EmberLeaflet.MarkerCollectionLayer.extend({
locationBinding: 'controller.item.center'});
App.MapView = EmberLeaflet.MapView.extend({
childLayers: [
EmberLeaflet.DefaultTileLayer,
App.MarkerCollectionLayer]
});
App.IndexController =
Ember.Controller.extend({});
JSON file:
{
"features": [
{
"headline": "Docker, the Linux container runtime: now open-source",
"center" : [40.714, -74.000]
},
{
"headline": "What's Actually Wrong with Yahoo's Purchase of Summly",
"center" : [40.714, -73.989]
}
]
}
The main fix needed here is the locationBinding in the MarkerCollectionLayer. The location binding needs to be in the MarkerLayer class. Furthermore, you need to use the EmberLeaflet.computed functions to convert simple lat lng arrays to a Leaflet LatLng object. See this example:
App.MarkerCollectionLayer = EmberLeaflet.MarkerCollectionLayer.extend({
content: Ember.computed.alias('controller'),
itemLayerClass: EmberLeaflet.MarkerLayer.extend({
location: EmberLeaflet.computed.latLngFromLatLngArray('content.center'),
})
});
Check out this JSFiddle with a full working example: http://jsfiddle.net/xALu4/2/
I am trying to use $.getJSON with Ember.js (Basically I am trying to avoid Ember-Data). Here's my code,
App = Ember.Application.Create();
App.Model = Ember.Object.extend({
});
App.Users = App.Model.extend({
id: null,
name: null
});
App.UsersRoute = Ember.Route.extend({
model: function(){
return App.Users.findAll();
}
});
App.Users.reopenClass({
findAll: function() {
var result = Ember.ArrayProxy.create({content: []});
$.getJSON('user.php', function(data) {
$.each(data, function(i, row) {
result.pushObject(App.Users.create(row));
});
});
return result;
}
});
and Here's my HTML:
<body>
<script type="text/x-handlebars" data-template-name="MyTemplate">
{{#each item in controller }}
<tr><td>
<p> {{item.name}}</p>
</td></tr>
{{/each}}
</script>
<script type="text/x-handlebars">
<h1>Application Template</h1>
{{outlet}}
</script>
</body>
Issue I am having is it is not the loading the model, do I need an controller too? Or anything else I am missing on my part?
You just have a small typo at the creation of the Application.
App = Ember.Application.create();
PS: Your code looks fine. Only the router mapping is missing, but i guess you left that one intentionally out of your example.
Update:
You should define a mapping for your UsersRoute:
App.Router.map(function() {
this.resource("users", { path: "/users" });
});
Your Template should be named accordingly as users:
<script type="text/x-handlebars" data-template-name="users">
{{#each item in controller }}
<tr><td>
<p> {{item.name}}</p>
</td></tr>
{{/each}}
</script>
And finally you should create a link to your Route in the main application template:
<script type="text/x-handlebars">
<h1>Application Template</h1>
{{outlet}}
{{#linkTo "users"}} Link to UsersRoute{{/linkTo}}
</script>