Saturday, February 21, 2015

Using the Controller As Syntax

Starting off from where the series "So You Want to Build a SPA" <http://buildspa.blogspot.com/> ended, we are going to apply the change in style relating how we bind the view to the controller. This style apparently was introduced with v1.2 (apparently after the original tutorial <https://docs.angularjs.org/tutorial> was written).  This style is used in the newer Code School course (highly recommended): <http://campus.codeschool.com/courses/shaping-up-with-angular-js/intro>.

A fellow (Todd Motto) has an excellent discussion in this change <http://toddmotto.com/digging-into-angulars-controller-as-syntax/>.

Starting from the source code from the So You Want to Build a SPA at <http://jsfiddle.net/sckmkny/y0Lfo7yt/> we apply the following changes.

First we need to update the routes with the "controllerAs" property; in this case I simply use simple names like "home" to reference the controller.

JavaScript
// routes/routes.js
angular.module('myApp').config(['$routeProvider',    
    function($routeProvider) {
        $routeProvider.
            when('/', {
                templateUrl: 'views/home.html',
                controller: 'HomeCntrl',
                controllerAs: 'home'
            }).
            when('/login', {
                templateUrl: 'views/login.html',
                controller: 'LoginCntrl',
                controllerAs: 'login'
            }).
            when('/wineries', {
                 templateUrl: 'views/wineries.html',
                 controller: 'WineriesCntrl',
                 controllerAs: 'wineries'
            }).
            when('/wines', {
                templateUrl: 'views/wines.html',
                controller: 'WinesCntrl',
                controllerAs: 'wines'
            }).
            otherwise({
                redirectTo: '/'
            });
    }
]);
// EOF

Next we update each of the controllers by removing the injection of "$scope" and attach those things that we want to be available to the view to the controller with the keyword "this".  We use the variable "ctrl" to avoid confusion as to what "this" is in nested code.

Below is the changes for just the home page controller; one needs to apply same sorts of changes to the remaining controllers: login, wineries, and wines.

JavaScript
controllers.controller('HomeCntrl', ['$location', '$window', function($location, $window) {
    var ctrl = this;
    var myDataRef;
    ctrl.navigate = function(path) {
        $location.path(path);
    };
    ctrl.authenticated = false;
    myDataRef = new $window.Firebase('https://wineapp.firebaseio.com');
    ctrl.logout = function() {
        ctrl.authenticated = false;
        myDataRef.unauth();
    };
    var authData = myDataRef.getAuth();
 if (authData != null) {
        ctrl.authenticated = true;
    }
}]);

Finally, we have to go back to the view and update all the naked references to now first reference the controller, e.g., "authenticated" is now "home.authenticated". Below is the updates for home; one needs to apply same sort of changes to login, wineries, and wines.

HTML
 

    
    <!-- /views/home.html (obmit work-around script tag)-->
    <script type="text/ng-template" id="views/home.html">
        <div class="panel panel-default">
            <div class="panel-heading">
                <h3 class="panel-title">Home</h3>
            </div>
            <ul class="list-group">
                <li ng-if="! home.authenticated" ng-click="home.navigate('/login');" class="list-group-item">Login</li>
                <li ng-if="home.authenticated" ng-click="home.logout();" class="list-group-item">Logout</li>
                <li ng-click="home.navigate('/wineries');" class="list-group-item">Wineries</li>
                <li ng-click="home.navigate('/wines');" class="list-group-item">Wines</li>
            </ul>
        </div>
    </script>
    <!-- EOF -->

No comments:

Post a Comment