SportsStore – Navigation and Checkout with AngularJS: Creating Partial Views

The HTML in the app.html file is approaching the point of complexity where it isn’t immediately obvious what every element does—something that will get worse as I add further features to the SportsStore application.

Fortunately, I can break up the markup into separate files and use the ng-include directive to import those files at runtime. To that end, I created the views/productList.html file, the contents of which are shown in Listing 7-3.

Listing 7-3. The Contents of the productList.html File

<div class=”panel panel-default row” ng-controller=”productListCtrl” ng-hide=”data.error”>

<div class=”col-xs-3″>

<a ng-click=”selectCategory()”

class=”btn btn-block btn-default btn-lg”>Home</a>

<a ng-repeat=”item in data.products | orderBy:’category’ | unique:’category'”

ng-click=”selectCategory(item)” class=” btn btn-block btn-default btn-lg”

ng-class=”getCategoryClass(item)”>

  {{item}}

</a>

</div>

<div class=”col-xs-8″>

<div class=”well”

ng-repeat=

“item in data.products | filter:categoryFilterFn | range:selectedPage:pageSize”>

<h3>

<strong>{{item.name}}</strong>

<span class=”pull-right label label-primary”>

{{item.price | currency}}

</span>

</h3>

<span class=”lead”>{{item.description}}</span>

</div>

<div class=”pull-right btn-group”>

<a ng-repeat=

“page in data.products | filter:categoryFilterFn | pageCount:pageSize”

ng-click=”selectPage($index + 1)” class=”btn btn-default”

ng-class=”getPageClass($index + 1)”>

 {{$index + 1}}

</a>

</div>

</div>

</div>

I have copied the elements that define the product and category lists into the HTML file. Partial views are fragments of HTML, which means that they do not require html, head, and body elements in the way that a complete HTML document does. In Listing 7-4, you can see how I have removed these elements from the app.html file and replaced them with the ng-include directive.

Listing 7-4. Importing a Partial View in the app.html File

<!DOCTYPE html>

<html ng-app=”sportsStore”>

<head>

<title>SportsStore</title>

<script src=”angular.js”></script>

<link href=”bootstrap.css” rel=”stylesheet” />

<link href=”bootstrap-theme.css” rel=”stylesheet” />

<script>

angular.module(“sportsStore”, [“customFilters”]);

</script>

<script src=”controllers/sportsStore.js”></script>

<script src=”filters/customFilters.js”></script>

<script src=”controllers/productListControllers.js”></script>

</head>

<body ng-controller=”sportsStoreCtrl”>

<div class=”navbar navbar-inverse”>

<a class=”navbar-brand” href=”#”>SPORTS STORE</a>

</div>

<div class=”alert alert-danger” ng-show=”data.error”>

Error ({{data.error.status}}). The product data was not loaded.

<a href=”/app.html” class=”alert-link”>Click here to try again</a> </div>

<ng-include src='”views/productList.html'”></ng-include>

</body>

</html>

Tip There are three benefits to using partial views. The first is to break up the application into manageable chunks, as I have done here. The second is to create fragments of HTML that can be used repeatedly in an application. The third is to make it easier to show different areas of functionality to the user as they use the application—I’ll return to this benefit in the “Defining URL Routes” section later in the chapter.

The creator of a directive can specify how it can be applied: as an element, as an attribute, as a class, or even as an HTML comment. I explain how this is done in Chapter 16, but the ng-include directive has been set up so that it can be applied as an element and as the more conventional attribute, and I have used it in this way solely for variety. When AngularJS encounters the ng-include directive, it makes an Ajax request, loads the file specified by the src attribute, and inserts the contents in place of the element. There is no visible difference in the content presented to the user, but I have simplified the markup in the app.html file and put all the product list-related HTML in a separate file.

Tip When using the ng-include directive, I specified the name of the file as a literal value in single quotes. If I had not done this, then the directive would have looked for a scope property to get the name of the file.

Source: Freeman Adam (2014), Pro AngularJS (Expert’s Voice in Web Development), Apress; 1st ed. edition.

Leave a Reply

Your email address will not be published. Required fields are marked *