Helpers not properly defined in application template? - ember.js

I'm extremely new to ember.js and am hitting a wall. I'm using ember.js 1.0.0-pre4
My app.js has the following setup:
window.App = Ember.Application.create();
App.Router.map(function() {
this.route("dashboard", {path: "/"});
});
App.DashboardRoute = Ember.Route.extend({
})
I tried doing something like this on the application template (Ember.TEMPLATES['application'])
{{#linkTo "dashboard"}}Dashboard{{/linkTo}}
And it gives me Uncaught Error: Could not find property 'linkTo'. I tried {{view}} as well as other helpers but all gave me the same could not find property error.
jsfiddle: http://jsfiddle.net/gBf42/

Aha, I found the problem! When you use Handlebars.compile it uses the handlebars script instead of the Ember script. Ember has its own handlebars object that extends the original Handlebars object with extra templates. One such template is the {{#linkTo ...}} template.
So to fix, all you have to do is use Ember.Handlebars instead:
Ember.TEMPLATES["application"] = Ember.Handlebars.compile("{{#linkTo 'dashboard'}}Dashboard{{/linkTo}}")

Related

Ember route map url with query parameters

this is my route configuration (route.js using ember-cli)
this.resource('xero-invoices', {path:'/loans/xero/:loan_id/invoices'})
but ember cuts query string when trying to route this address . How to fix problem?
The portion of your route definition had a minor typo missing a closing curly brace, but I am assuming that is not really the issue. Here it is fixed for clarity.
this.resource('xero-invoices', {path:'/loans/xero/:loan_id/invoices'})
The resource above has a dynamic segment of lone_id not a query string. Query string support is currently in the beta builds of Ember and not in stable. Any query string functionality you are trying to use would be handled in your controller. http://emberjs.com/guides/routing/query-params/
If you had a jsbin or more code I may be more helpful.
Here is a trivial jsbin showing the dynamic segment working - http://emberjs.jsbin.com/casana/1/edit
Edit:
In your example jsbin you are trying to use the (query-parms) helper for link-to which is only available if you are using the beta version of Ember. In your application controller if you remove it from your application template you won't get an error. In your route, since you are returning the query param as the model, the oauth_token is accessible via the model property in the controller.
Source: http://jsbin.com/bufukiqisika/8/edit
App = Ember.Application.create();
App.Router.map(function() {
this.resource('xero-invoices', { path:'/loans/xero/:loan_id/invoices' });
});
App.IndexRoute = Ember.Route.extend({
model: function() {
return ["red","blue","green"];
}
});
App.XeroInvoicesRoute = Ember.Route.extend({
model: function(params) {
window.console.log(params);
return params.queryParams["oauth_token"];
}
});
Templates:
<script type="text/x-handlebars">
<h2>Welcome to Ember.js</h2>
{{outlet}}
</script>
<script type="text/x-handlebars" data-template-name="xero-invoices">
{{model}}
</script>
Example: http://jsbin.com/bufukiqisika/8#/loans/xero/09870987/invoices?oauth_token=foo
You can use query-parameters which are defined on controllers.
Something like this should work:
MyController = Ember.Controller.extend({
queryParams: ['searchvalue'],
searchvalue : null
})
And in you Template:
{{input type="text" valueBinding=controller.searchvalue}}
So your search value will be represented in the URL, e.g. “…/myapp/seach?searchvalue=foo”
See http://emberjs.com/guides/routing/query-params/

Ember.js RC1 - view not displayed when specifying 'template'

Following the Ember guide on templates I do the following:
App.PostsView = Ember.View.extend({
template: Ember.Handlebars.compile('I am the template')
});
But nothing is rendered. When I use the templateName the view is rendered:
// html
<script type='text/x-handlebars' data-template-name='posts-template'>
<h1>I am the template</h1>
</script>
// js
App.PostsView = Ember.View.extend({
templateName: 'posts-template'
});
How can I get the templates to work using the template function as stated in the guides?
edit:
I did come across these:
emberjs template compile doesn't work in rc1
How do I specify using a view with a compiled handlebar in ember.js RC1
So this might look like a duplicate. However, this first appears to use some extra work not specified in the Ember guides and the second is what I am doing but it is not working.
OK, this works:
Ember.TEMPLATES['posts-template'] = Ember.Handlebars.compile('I am the template');
App.PostsView = Ember.View.extend({
templateName: 'posts-template'
});
What was happening in our was that our pre-compiled templates were being added to Handlebars.templates and not Ember.TEMPLATES along with the fact that we were returning the complied template using this, e.g.:
App.PostsView = Ember.View.extend({
template: Handlebars.templates['posts-template']
});
So it seems as though one should refrain from interfering with the template function but rather always use the templateName which will be looking for that name in Ember.TEMPLATES.
Hopefully this helps someone save some time :)
You can also specify the expected templateName along with the actual template contents:
App.PostsView = Ember.View.extend({
templateName: 'posts',
template: Ember.Handlebars.compile('I am the template')
});
JSBin example

ember.js template not rendered

While it doesn't become simpler than this: fiddle I can't get the template to be rendered. I'm obviously missing something simple but have been starring at this for hours now. Can somebody spot the error?
When debugging in chrome I can see that the View is entered as well as the controller, but the template doesn't seem to come to life. I have several other ember tests running on my laptop that render just fine.
<script type="text/x-handlebars" data-template-name="index">
<h1>Application</h1>
<p>Your content here.</p>
{{outlet}}
</script>
Albumartist = Ember.Application.create();
Albumartist.Router.map(function(match) {
this.route('index', {path: '/'});
});
Albumartist.IndexView = Ember.View.extend({
});
Albumartist.IndexRoute = Ember.Route.extend({
});
Albumartist.IndexController = Ember.Controller.extend({
renderTemplate: function(controller, model){
console.log('hi');
}
});
The problem is simple: You chose Ember as a Framework didn't include jQuery, which is necessary for Ember to run. I've updated the Fiddle to include Ember and Handlebars as a resource and jQuery as a Framework.
Also, since Router v2.1 you don't have to pass the match argument to the router:
Albumartist.Router.map(function() { // no match argument needed anymore
this.route('index', {path: '/'});
});
If I am not mistaken, you need to wrap your code in <script> tags which appear to be missing. This could possibly by a typo when copying your code over to this site though.

why view. is needed in handlebars

I can't understand something in Ember.js, my contains a property, but in order to display it i have to do {{view.property}}, why can't I simple use {{property}} ?
in the following example only {{view.test}} is displayed.
shouldn't the view be the default scope ?
index.html:
<script type="text/x-handlebars" data-template-name="places">
{{test}} {{view.test}}
</script>
app.js:
App.PlacesController = Ember.ArrayController.extend({
});
App.PlacesView = Ember.View.extend({
templateName: 'places',
test: 'test'
});
As of Ember 1.0pre, the context for handlebars helpers in your template has been changed to be the controller.
Before that, it was the view. The view keyword is available to access properties from the view.
Try adding a test property to your controller and see what happens.

ember.js routers and connectOutlets

I'm trying to use an already instantiated controller in my ember route.
Is it not normal to ever have instantiated a controller and want to use that in a route? I know that if I the application instantiate a controller for me, I can then to router.get("myController") but that won't access one that I had instantiated myself.
How do I get the piece of code at the bottom of my router to work?
HTML
<script type="text/x-handlebars" data-template-name="application">
{{outlet}}
</script>
<script type="text/x-handlebars" data-template-name="instanced">
<h1>Hello from instanced template</h1>
{{showinstancedvalue}}<hr>
{{outlet}}
</script>
<script type="text/x-handlebars" data-template-name="foobar">
<h1>hello from foobar</h1>
{{foobarvalue}}
</script>
Javascript
var App = Ember.Application.create();
// application view and controller
App.ApplicationView = Ember.View.extend({
templateName: 'application',
});
App.ApplicationController = Ember.Controller.extend();
// foobar controller and view
App.FoobarController = Ember.Controller.extend({
foobarvalue: "working"
});
App.FoobarView = Ember.View.extend({
templateName: 'foobar'
});
// instantiated controller and view
App.InstancedController = Ember.Controller.extend({});
App.instancedController = App.InstancedController.create({
myvar: "a value from an instantiated controller"
});
App.InstancedView = Ember.View.extend({
templateName: 'instanced',
});
App.instancedView = App.InstancedView.create({
showinstancedvalueBinding: 'App.instancedController.myvar'
});
App.instancedView.append();
App.router = Ember.Router.create({
enableLogging: true,
root: Ember.Route.extend({
index: Ember.Route.extend({
route: '/',
redirectsTo: 'works'
}),
works: Ember.Route.extend({
route: '/works',
connectOutlets: function(router) {
router.get('applicationController').connectOutlet('foobar');
}
}),
broken: Ember.Route.extend({
route: '/broken',
connectOutlets: function(router) {
// no error in console, but foobar doesn't appear
// router.get('instancedController').connectOutlet('foobar');
// *** this one was my best guess as to what I thought would work ***
// no error in console, but foobar doesn't appear
// App.instancedController.connectOutlet('App.Foobar');
// Uncaught Error: assertion failed: The name you supplied foobar did not resolve to a view FoobarView
// App.instancedController.connectOutlet('foobar');
}
}),
})
});
App.initialize(App.router);​
Take a look at the connectOutlet definition, it includes a basic documentation as a comment so you can have a better understanding of how it's supposed to or and to be used.
Basically, you should really connect it to the applicationController, since the {{outlet}} sits on the ApplicationView template. In this scenario, the framework will find a view and controller that should be used in that state (in your case FoobarView and foobarController since it's specified with the argument 'foobar') and add to a collection (named controllers) inside the applicationController. If you try to connect directly to your instance of foobarController, it won't find a outlet on its view (which at that moment shouldn't be instantiated, I believe) AND you'd be saying to that controller "hey, find yourself, then connect yourself to you" kind of thing.
This could work if you had an outlet inside the foobar view template and you'd connect this outlet to something other than foobar (as a child state/route). So you should read more about the outlets and named outlets.
Additionally, I strongly recommend these links:
Router Primer - This article is about two weeks fresh, and it's apparently the best there is right now, make sure you read this one!
Ember.js Routing - the Director’s Cut - Step-by-Step post about the Router, make sure you read this one too.
Outlets - This is a bit old but is being mantained
JSFiddle Sample 1 - Sample Fiddle with routing you can use as reference
JSFiddle Sample 2 - Sample Fiddle with routing you can use as reference (this is newer than previous)
You should try to elaborate on your requirements. This makes no sense from my point of view.
broken: Ember.Route.extend({
route: '/broken',
connectOutlets: function(router) {
App.foobarController.connectOutlet('foobar');
}
}),
This code just can't work, since you are invoking connectOutlet on your fooBarController. So it searches for {{outlet}} in the assigend view. But in the template named foobar you do not not have a {{outlet}} specified. And even if you fix that, it makes just no sense, since this line would try to connect an outlet with a new instance of Foobar View. So you basically have the FooBarView of your FooBarController and inside its view, you try to connect a outlet again with a new instance of FooBarView??
So without explanation of requirements this question cannot be answered.