Before getting into handlebars, let's look at how routing works in Ember.js. Router is solely responsible for all URLs in Ember.
Linking to Routes
Router is solely responsible for all URLs in Ember. Let's inspect the app.js
and index.html
files.
app.js
App.router.map(function() {
this.route('about');
});
index.html
<a href="#">Home</a>
<a href="#/about">About</a>
It is considered a bad practice to do this. We don't hard code URL paths. Instead, we ask the routes for their path.
The Handlebars link-to helper
Use the route name to look up the path
{{#link-to 'index'}}Homepage{{/link-to}}
{{#link-to 'about'}}about{{/link-to}}
The link-to will determine the path based on the route name. The code above will generate the following HTML:
<a href="#/" class="ember-view" id="ember2">Homepage</a>
<a href="#/about" class="ember-view" id="ember3">About</a>
Extra Attributes
How to add a custom class to our link.
{{#link-to 'index' class='nav-brand'}Home{{/link-to}}
The above code will be rendered from template into
<a href="#/" class="ember-view" id="ember2">Homepage</a>
tagName option
How to change the HTML element
{{#link-to 'index' tagName='li'}Home{{/link-to}}
{{#link-to 'about' tagName='li'}
About{{/link-to}}
The above code will be rendered from template into
<li class="ember-view" id="ember1">Home
<li class="ember-view" id="ember2">About
Notice how href disappeared and now it is a list instead of a link. But the click still works as Ember adds click handlers.
Template Variables
You can use properties in your template, like the productsCount below
<script type='text/handlebars' data-template-name='index'>
There are {{productsCount}} products
</script>
How do you set a property for use in a template?
Ember Controller
Ember COntroller provides properties for the template. Ember Controller is where a template looks to find a property value. It decorates your applications data for the template and contains information that is not saved to a server.
Asking the Controller:
<script type='text/x-handlebars' data-template-name='index'>
There are {{productsCount}} products
</script>
Above code looks for a controller named IndexController, and the property inside it.
App.IndexController = Ember.Controller.extend({
productsCount: 5
});
Every Route has a Default Controller
Consider the code below:
App.Router.map(function() {
this.route('about');
});
Behind the scenes, Ember creates this About controller.
App.AboutController = Ember.Controller.extend({ });
If we want to declare properties that get rendered inside a template, then we can declare this Controller.
Binding with Metamorph
<script type='text/x-handlebars' data-template-name='index'>
There are {{productsCount}} products
</script>
This will render as below:
There are
<script id="metamorph-2-start" type="text/x-placeholder"></script>
5
<script id="metamorph-2-end" type="text/x-placeholder"></script>
products
Ember needs to wrap properties so it can potentially update it later. (AKA. Binding)
How to Bind Attributes
<script type='text/x-handlebars' data-template-name='index'>
There are {{productsCount}} products
<img {{bind-attr src='logo'}} alt='Logo' />
</script>
In the rendered html, Ember meta data is still added to enable binding. (data-nindattr-1)
<img src="/images/logo.png" data-bindattr-1="1">
Dynamic Content
How do we fetch the current time?
<script type='text/x-handlebars' data-template-name='index'>
Rendered on {{time}}
</script>
We need to create a property that calls this function:
(new Date()).toDateString()
This is more then just a value, we need to execute some code to get the value.
Controller Functions
We need to tell Ember this is a property and to call it
App.IndexController = Ember.Controller.extend({
productsCount: 6,
logo: '/images/logo.png',
time: function() {
return;
}
});
Controller Functions as Properties
<script type='text/x-handlebaaprps.'js data-template-name='index'>
Rendered on {{time}}
</script>
time will be called, and that value used as a property
App.IndexController = Ember.Controller.extend({
productsCount: 6,
logo: '/images/logo.png',
time: function() {
return
}
});
Linking to Routes
Router is solely responsible for all URLs in Ember.
app.js
App.router.map(function() {
this.route('about');
});
index.html
<a href="#">Home</a>
<a href="#/about">About</a>
It is considered a bad practice to do this. We don't hard code URL paths. Instead, we ask the routes for their path.
The Handlebars link-to helper
Use the route name to look up the path
{{#link-to 'index'}}Homepage{{/link-to}}
{{#link-to 'about'}}about{{/link-to}}
The link-to will determine the path based on the route name. The code above will generate the following HTML:
<a href="#/" class="ember-view" id="ember2">Homepage</a>
<a href="#/about" class="ember-view" id="ember3">About</a>
Extra Attributes
How to add a custom class to our link.
{{#link-to 'index' class='nav-brand'}Home{{/link-to}}
The above code will be rendered from template into
<a href="#/" class="ember-view" id="ember2">Homepage</a>
tagName option
How to change the HTML element
`html
{{#link-to 'index' tagName='li'}Home{{/link-to}}
{{#link-to 'about' tagName='li'}
About{{/link-to}}
The above code will be rendered from template into
```html
<li class="ember-view" id="ember1">Home
<li class="ember-view" id="ember2">About
Notice how href disappeared and now it is a list instead of a link. But the click still works as Ember adds click handlers.
Template Variables
You can use properties in your template, like the productsCount below
<script type='text/handlebars' data-template-name='index'>
There are {{productsCount}} products
</script>
How do you set a property for use in a template?
Ember Controller
Ember COntroller provides properties for the template. Ember Controller is where a template looks to find a property value. It decorates your applications data for the template and contains information that is not saved to a server.
Asking the Controller:
<script type='text/x-handlebars' data-template-name='index'>
There are {{productsCount}} products
</script>
Above code looks for a controller named IndexController, and the property inside it.
App.IndexController = Ember.Controller.extend({
productsCount: 5
});
Every Route has a Default Controller
Consider the code below:
App.Router.map(function() {
this.route('about');
});
Behind the scenes, Ember creates this About controller.
App.AboutController = Ember.Controller.extend({ });
If we want to declare properties that get rendered inside a template, then we can declare this Controller.
Binding with Metamorph
<script type='text/x-handlebars' data-template-name='index'>
There are {{productsCount}} products
</script>
This will render as below:
There are
<script id="metamorph-2-start" type="text/x-placeholder"></script>
5
<script id="metamorph-2-end" type="text/x-placeholder"></script>
products
Ember needs to wrap properties so it can potentially update it later. (AKA. Binding)
How to Bind Attributes
<script type='text/x-handlebars' data-template-name='index'>
There are {{productsCount}} products
<img {{bind-attr src='logo'}} alt='Logo' />
</script>
In the rendered html, Ember meta data is still added to enable binding. (data-nindattr-1)
<img src="/images/logo.png" data-bindattr-1="1">
Dynamic Content
How do we fetch the current time?
<script type='text/x-handlebars' data-template-name='index'>
Rendered on {{time}}
</script>
We need to create a property that calls this function:
(new Date()).toDateString()
This is more then just a value, we need to execute some code to get the value.
Controller Functions
We need to tell Ember this is a property and to call it
App.IndexController = Ember.Controller.extend({
productsCount: 6,
logo: '/images/logo.png',
time: function() {
return;
}
});
Controller Functions as Properties
<script type='text/x-handlebaaprps.'js data-template-name='index'>
Rendered on {{time}}
</script>
time will be called, and that value used as a property
App.IndexController = Ember.Controller.extend({
productsCount: 6,
logo: '/images/logo.png',
time: function() {
return
}
});