EMBER & HANDLEBARS
- development
- javascript
- ember.js
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>
<li class="ember-view" id="ember2">About</li>
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/blog/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/blog/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/blog/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`
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/blog/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/blog/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/blog/logo.png',
time: function () {
return;
},
});