Getting Started with AngularJS


AngularJS

AngularJS is a JavaScript framework – being JavaScript means it is primarily meant for fast, responsive web applications. A framework, in turn, is a set of tools (classes, methods, directives, etc.) that help save you typing because you don’t keep writing the same code over and over, and the result is much better still than when you rely only on plain JS and your own skills.

It is developed and was mostly created by people from this company, but anyone can look into its source code, because it is open-source. A big major update numbered 2 is currently in the works, and it won’t be very compatible with version 1.x (the v2 beta can be downloaded at https://angular.dev/ ). The stable 1.x version is available at https://angularjs.org/ .

I’ll share some TypeScript code with you, which was my first real project in AngularJS and is used on the page 👻 This address now lives only in the archive of my memories..
sunamo.cz is a website that contains many sites on different topics, each in its own directory – partly for easy sharing of code and of the individual sites – and the same applies to TypeScript. That’s why I have .ts files shared by all sites, then files that can be used only by the site they belong to, which is always just a single file named Shared.ts (e.g. in ts/GeoCaching), and finally files that relate only to a specific page.

I won’t copy the rest of the code here, only the part that works with AngularJS. So first, the code in Shared.ts:

JS
var app: function($scope)
{
});

Here I have a single module for the whole geocaching.sunamo.cz site. That’s the right way, but definitely don’t be stingy with modules – ideally use one for every component that is used in more than one place, see https://docs.angularjs.org/guide/module . It is attached to the page’s DOM using ng-app.

The second parameter is an array of modules it depends on. Without ngRoute you can hardly do anything at all, because it is what makes directives work (I’ll try to explain below). Then I create the module’s controller. A controller is the intermediary between the module and the view – exactly in the spirit of MVC. It should only be used to set the initial values of the scope and adjust its behavior.

Now let’s look at the file PublicGpxTracks.ts:

JS
//-Tell the top-level application module to load and use the geoPublicGpxTracksTable module
app.requires.push("geoPublicGpxTracksTable");
//-Create the module, no need to attach ngRoute because it already comes from the base module geoSunamoCz
var appPublicGpxTracks: function($scope)
{
    //-Set the default values for the table after the page loads
    $scope.sortType = 'firstStep'; // Set the default column to sort by after the page loads
    $scope.sortReverse = false;  // Whether to sort in descending order
    $scope.searchComment = '';     // text search filter
    $scope.userId = 1;
    //-Load objects from a classic json array [{...}, ...]
    var o = $("#hfPublicGpxTracks").val();
    var s = ToString(o);
    var js = jQuery.parseJSON(s);
    $scope.tracks = js;
});

The comments are right in the code, so there’s no need to comment on it any further – once you see the HTML, everything will make sense:

XML
<div data-ng-app="geoPublicGpxTracksTable" data-ng-controller="mainController">
    <input id="hfPublicGpxTracks" type="hidden" />
    <input id="hfIdUser" name="hfIdUser" type="hidden" data-ng-model="userId" />
    <div class="naStred" style="text-align: center;">
        &nbsp;
        <div>
            Search in file name:
            <div class="input-control text">
                <input type="text" placeholder="Name or place" data-ng-model="searchFileName" />
            </div>
            &nbsp;
        </div>
        &nbsp;
        <table class="naStred" border="1">
            <thead style="color: white; background-color: black;">
                <tr>
                    <td>Order</td>
                    <td>
                        <a href="#" data-ng-click="sortType = 'date'; sortReverse = !sortReverse">Date</a>
                    </td>
                    <td>
                        <a href="#" data-ng-click="sortType = 'firstSegment'; sortReverse = !sortReverse">First segment</a>
                    </td>
                    <td>
                        <a href="#" data-ng-click="sortType = 'lastSegment'; sortReverse = !sortReverse">Last segment</a>
                    </td>
                    <td>
                        <a href="#" data-ng-click="sortType = 'countSegment'; sortReverse = !sortReverse">Number of segments</a>
                    </td>
                    <td>
                        <a href="#" data-ng-click="sortType = 'time'; sortReverse = !sortReverse">Total time</a>
                    </td>
                    <td>
                        <a href="#" data-ng-click="sortType = 'lowestPoint'; sortReverse = !sortReverse">Lowest point</a>
                    </td>
                    <td>
                        <a href="#" data-ng-click="sortType = 'highestPoint'; sortReverse = !sortReverse">Highest point</a>
                    </td>
                    <td>
                        <a href="#" data-ng-click="sortType = 'km'; sortReverse = !sortReverse">Distance walked</a>
                    </td>
                    <td>
                        <a href="#" data-ng-click="sortType = 'averageSpeed'; sortReverse = !sortReverse">Average speed</a>
                    </td>
                    <td>
                        <a href="#" data-ng-click="sortType = 'fileNameWithoutExtension'; sortReverse = !sortReverse">File name</a>
                    </td>
                </tr>
            </thead>
            <tbody>
                <tr data-ng-repeat="track in tracks | orderBy:sortType:sortReverse | filter:searchFnwoe">
                    <td>
                        <span class="dead-link" title="Broken link: http://www.for-you-the.best/GeoCaching/ShowGpxTrack.aspx?code={{track.code}}&amp;idUser={{userId}}" style="color:#8a6d3b;background:#fcf8e3;border:1px dashed #d9c48a;padding:1px 5px;border-radius:3px;">&#128123; This link died before ICQ did.</span>
                    </td>
                    <td>{{ track.date | date:'yyyy-MM-dd' }}</td>
                    <td>{{ track.firstSegment | date:'HH:mm:ss' }}</td>
                    <td>{{ track.lastSegment | date:'HH:mm:ss' }}</td>
                    <td>{{ track.countSegment }}</td>
                    <td>{{ track.time | date:'HH:mm:ss' }}</td>
                    <td>{{ track.lowestPoint }} m a.s.l.</td>
                    <td>{{ track.highestPoint }} m a.s.l.</td>
                    <td>{{ track.km }} km</td>
                    <td>{{ track.averageSpeed }} m/s</td>
                    <td>{{ track.fileNameWithoutExtension }}</td>
                </tr>
            </tbody>
        </table>
        &nbsp;
    </div>
    &nbsp;
</div>

Directives used:

data-ng-click – what should happen when the element is clicked. Setting a single variable belonging to $scope updates the data in the module

data-ng-repeat – processes the collection and, based on the HTML code inside, displays each of its items

ng-model – a variable in the $scope of the current controller to which the value of an attribute or element is bound in both directions

 

Filters used with the ng-repeat directive:

orderBy – sorts the items. It works with any standard data type. The second parameter is a bool – it is optional and determines whether to sort in descending order (DESC).

filter – keeps only the items that contained the given object of any type

 

Variables used with the ng-repeat directive:

$index – returns the index of the current iteration, counted from zero

If you want to output the value of a variable into the HTML output, wrap it in double curly braces (for example {{ objekt.promenna }}. This can also be used inside XML attributes.

Categories

Leave a Reply