S
All posts

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.

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.

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