AngularJS: A Walk-Through - Week 6

Sample web application from week 6 of the course AngularJS: A Walk-Through. <http://angularjs-walk.blogspot.com/>

by John Tucker

HTML

<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.9/angular.min.js"></script>
<link rel="stylesheet" href="//dhg7upb7j7jqa.cloudfront.net/shaping_up_with_angular_js/assets/demo/bootstrap.min.css">
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.9/angular-route.js"></script>
<!-- index.html (part of) -->
<div ng-view></div>

<!-- marketing/about.html -->
<script type="text/ng-template" id="marketing/about.html">
    <h2>About this store</h2>
    <p><a href="#/">Back</a></p>
</script>

<!-- store/store.html -->
<script type="text/ng-template" id="store/store.html">
    <!--  Store Header  -->
    <header>
        <h1 class="text-center">Flatlander Crafted Gems</h1>
        <h2 class="text-center">– an Angular store –</h2>
        <p class="text-center"><a href="#/about">About</a></p>
    </header>
    
    <!--  Products Container  -->
    <div class="list-group">
        <!--  Product Container  -->
        <div class="list-group-item" ng-repeat="product in storeVM.products">
            <h3>{{product.name}} <em class="pull-right">{{product.price | currency}}</em></h3>        
            <!-- Image Gallery  -->
            <product-gallery></product-gallery>
            
            <!-- Product Tabs  -->
            <product-tabs></product-tabs>
        </div>
    </div>
</script>

<!-- store/product-description.html -->
<script type="text/ng-template" id="store/product-description.html">
    <!--  Description Tab's Content  -->
    <div ng-show="tabVM.isSet(1)">
        <h4>Description</h4>
        <blockquote>{{product.description}}</blockquote>
    </div>
</script>

<!-- store/product-specs.html -->
<script type="text/ng-template" id="store/product-specs.html">
    <!--  Spec Tab's Content  -->
    <h4>Specs</h4>
    <ul class="list-unstyled">
      <li>
        <strong>Shine</strong>
        : {{product.shine}}</li>
      <li>
        <strong>Faces</strong>
        : {{product.faces}}</li>
      <li>
        <strong>Rarity</strong>
      ...

CSS

.ng-invalid.ng-dirty {
  border-color: red;
}
.ng-valid.ng-dirty {
  border-color: green;
}

JavaScript

// app.js
(function() {
    angular
        .module('app', ['ngRoute', 'marketingModule', 'storeModule'])
        .config(['$routeProvider', routes]);
    function routes($routeProvider) {
        $routeProvider.
        when('/', {
            templateUrl: 'store/store.html',
            controller: 'StoreController'
        }).
        when('/about', {
            templateUrl: 'marketing/about.html',
            controller: 'AboutController'
        }).
        otherwise({
            redirectTo: '/'
        });
    }
})();

// marketing/marketing.module.js
(function() {
    angular
        .module('marketingModule', []);
})();

// marketing/about.controller.js
(function() {
    angular
        .module('marketingModule')
        .controller('AboutController', AboutController);
    function AboutController() {
    }
})();

// marketing/store.module.js
(function() {
    angular
        .module('storeModule', []);
})();

// store/store.controller.js
(function() {
    angular
        .module('storeModule')
        .controller('StoreController', ['gemsService', StoreController]);
    function StoreController(gemsService) {
        var vm = this;
        vm.products = gemsService;
    }
})();

// store/product-description.directive.js
(function() {
    angular
        .module('storeModule')
        .directive("productDescription", productDescription);
    function productDescription() {
         return {
                restrict: 'E',
                templateUrl: "store/product-description.html"
            };
    };
})();

// store/product-reviews.directive.js
(function() {
    angular
        .module('storeModule')
        .directive("productReviews", productReviews);
    function productReviews() {
        return {
            restrict: 'E',
            templateUrl: "store/product-reviews.html",
            controller: ReviewController,
            controllerAs: "reviewVM"
        };
    }
    function ReviewController() {
        var vm = this;
        vm.review...