Connecting controllers

Sometimes, especially in nested routes, the nested controller would want access to the model or data from the parent controller. The Ember.js framework provides us with the ability to link two or more controllers together so that the state of one controller can be accessed from the other one. Such a link between two controllers is not limited to only nested routes, but to any controller that wants to access another controller.

Let us see this in an example. We will continue with our preceding example of showing a list of products to end users. After creating a view to show all the products in a tabular form, let's move on to creating a page for an individual product and another one to show the reviews for a specific product.

Let's start by adding the routes in app/router.js, as follows:

Router.map(function() {
  this.resource("products");
  this.resource("product",{path: "/:id"},function(){
    this.route("reviews");
  });

});

Router code is present at app/router.js

After adding in the two additions in router.js, let's move on to creating the corresponding routes as follows:

import Ember from "ember";

export default Ember.Route.extend({
  model: function(params){
    return {"id": 1, "name" : "Leather Jacket" , "description" : "A very long jacket description which cannot be shown inside a table and will have to be shortened",
      "currency": "USD" , "symbol": "$" , "price":"1999.999" , "dimensions": {"length": 7.0,"width": 12.0,"height": 9.5}
    }
  }
});

Product route is present at app/routes/product.js

The product route is straightforward and self-explanatory.

Let's look at the reviews route in the following:

import Ember from "ember";

export default Ember.Route.extend({
  model: function(){
    return ["This is a great jaket","Another Review","AwesomeJacket","Too pricy"];
  }
});

The product/reviews route is present at app/routes/product/reviews.js

The reviews route is simple and returns the reviews related to a product. Here, we always return a static list of reviews. In a real scenario, you would fetch the reviews related to a product from the server.

Let's look at the reviews controller:

import Ember from "ember";

export default Ember.ArrayController.extend({
  needs:["product"],
  product: Ember.computed.alias("controllers.product")
});

The product/reviews controller is present at app/controllers/product/reviews.js

The Ember.js framework provides us with the needs keyword to manage dependencies between controllers. The needs property expects the names of controllers that the current controller wants access to. In our case, we need to show the name of the product for which the review has to been written. Now, since the product object is set in the model property of the product controller, we would need access to the product controller to fetch the name of the product for which the review has been written.

The controllers made available by the needs property can be accessed by using the controllers.product convention. To make it simpler, we make an alias product, pointing to controllers.product.

Now, to access the name of the product for which the review has been written, we can use {{product.name}}:

<h2> Reviews for {{product.name}}</h2>
<table class="table table-bordered">
  <thead>
    <tr>
      <th data-field="name">Reviews</th>
    </tr>
    {{#each review in controller}}
    <tr>
      <td>{{review}}</td>
    </tr>
    {{/each}}
  </thead>
</table>

The reviews template is present at app/templates/product/reviews.js

Tip

Unlike traditional MVC frameworks, the controllers in the Ember.js framework are singleton, which means that during a browser session, the same instance of controller is returned and shared across the application. Whenever you change your route, the controller is not destroyed and keeps its state intact. When the user interacts with the application only, the model is fetched again and the template bound to the route is updated with the correct data.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.146.221.144