Series “Developing applications on single-Angular.js”

  1. Why do I need Angular.js and why he
  2. Modern tools and framework Angular.js frontend applications
  3. Familiarity with controllers and directives Angular.js
  4. Writing Services in Angular.js
  5. Routing in Angular.js
  6. How to connect to the API backend Angular.js

In this article we will write a simple controller Angular.js and make it display the data in this table using the built-in Angular directives. Moreover, we revive this form so that it really adds a new row to the table transactions.

Controllers Angular.js are the link between the html-marking and a “model”. The Angular model responsible for just 4 different kinds of objects, which we will discuss later. Omit is that the model and will store all of the data directly in the controller.

The task of the controller, as well as in other MVC frameworks, is to obtain data from the model and display it to the user, or in the other direction, to obtain data from the view and sending them to the model.

First of all, remove src/app/main.controller.js, src/app/main.controller.spec.js, src/app/main.html and src/components/navbar/, which generated the Yeoman for us.

Writing the first controller

Our first controller will be called TransactionsCtrl. According to the naming conventions in Angular.js, controller name is constructed as a “name + Ctrl”.

Create a file src/app/main/transactions.controller.js. In this file, define the controller itself:

//src/app/main/transactions.controller.js
 angular. module ( "ngmkdev") . controller ( 'TransactionsCtrl', function ($ scope) {

 });

Note that we do not need to connect the newly created file manually using the tag <script>. When we run gulp serve, Gulp will begin to monitor changes to files and folders and update the temporary index.html inside the folder .tmp/ (he, by the way, and is loaded when you open the browser localhost:4567). And when it comes time to collect the final version of the application, the command gulp build will do the same and return to us the necessary index.html with pressed down or attached files, necessary libraries and applications.

At this stage, we will not break layout application into multiple files and directly edit src/index.html (and so we removed the folder components/navbar/ and main.html ).

The index.html file replace <div ui-view></div> on the following simple layout:

<!-- src/index.html -->
<div ui-view class="container">
  <div class="col-xs-2">
    <h2>Money</h2>
    <h3 class="money-ok">
      500.0
    </h3>
    <ul class="nav nav-pills nav-stacked">
      <li>
        <a href="#"><i class="glyphicon glyphicon-th-list"></i> Transations</a>
      </li>
      <li>
        <a href="#"><i class="glyphicon glyphicon-tasks"></i> Settings</a>
      </li>
    </ul>
  </div>
  <div class="col-xs-6">
    <h2>Transations</h2>

    <br>
  </div>
</div>

Note: we have not spent a single second on the manual connection Boostrap, but soon moved to its use. Many developing routine processes are automated: we only need to impose himself layout. On connecting the files will take care Gulp, and of a beautiful appearance – Bootstrap.

Now you need to determine the controller on some the html-element in our application to have access to the controller inside and we could use the data from the controller inside the html.

It is best suited for this central unit with the transaction. Define the controller on the parent unit using directives ng-controller:

<!-- src/index.html -->
<div class="col-xs-6" ng-controller="TransactionsCtrl as transactions_ctrl">
   <h2>Transations</h2>
   <br>
</div>

Directive Angular.js responsible for adding new functionality html-markup. This directive goes through the connection of your js-code interface. ng-controller – one of the simplest and most important directives. She attributes part of html code to a particular controller, makes available $scope of this controller inside the html element.

What is the $scope?

$scope – is an object, through which we can get in the html code of access to the data from the model and controller. In Angular.js implemented a complex system upgrade and inheritance Scope. The most important is the $rootScope, which is defined on the entire application and accessible from any part of the code. Controllers provide a $scope, which is available in html-element on which this controller is defined.

Starting with version 1.2, in Angular.js a new syntax for accessing the controller from html: specifying as transactions_ctrl to $scope of this element defines a new object corresponding to the controller. All that we define in TransactionsCtrl controller through this will be available through transactions_ctrl. Thus solving the problem of nested $scope – we always know exactly how to Scope we work.

Let’s see this behavior as an example. Define attribute transactions for the controller as follows:

//src/app/main/transactions.controller.js
angular.module('ngmkdev').controller('TransactionsCtrl', function($scope) {
  this.transactions = [
    { amount: 500.00, date: "08/08/2014", description: "Subscribe to the magazine" },
    { amount: 150.00, date: "07/08/2015", description: "Cocaine" }
  ]
});

And I will bring the transaction using another directive – ng-repeat, responsible for the removal of the collections. Its syntax is self-explanatory.

<!-- src/index.html -->
<div class="col-xs-6" ng-controller="TransactionsCtrl as transactions_ctrl">
  <h2>Transactions</h2>
  <br>
  <table class="table table-striped">
    <thead>
      <tr>
        <th>Sum</th>
        <th>Date</th>
        <th>Descriptions</th>
        <th>Actions</th>
      </tr>
    </thead>
    <tbody>
      <tr ng-repeat="transaction in transactions_ctrl.transactions">
        <td>{{transaction.amount}}</td>
        <td>{{transaction.date}}</td>
        <td>{{transaction.description}}</td>
        <td></td>
      </tr>
    </tbody>
  </table>
</div>

To print something from the controller to the screen the user uses braces. Angular.js uses existing template engines like Handlebars or Mustache. Instead, the framework is built right into your template.

But of course we need – we need a way to add new transactions. To do this, we mark up a simple form, paste it immediately after the header <h2>Transactions</h2>:

<!-- src/index.html -->
<form class="form-inline">
  <div class="form-group">
    <div class="input-group">
      <div class="input-group-addon">$</div>
      <input class="form-control" type="text" placeholder="Amount">
    </div>
  </div>
  <div class="form-group">
    <label class="sr-only"></label>
    <input type="text" class="form-control" placeholder="Description">
  </div>
  <button type="submit" class="btn btn-default">Add</button>
</form>

Add a template for a new transaction to the controller:

// src/app/main/transactions.controller.js

// ...
  this.resetTransaction = function() {
    this.newTransaction = {
      amount: 0.0,
      date: "01/02/1993",
      description: null
    }
  }
  this.resetTransaction();
// …

The current transaction will be equal to the workpiece from the function immediately after initialization controller resetTransaction().

Now you need to associate the shape of the object newTransaction . To do this, we will use the directive ng-model, which links form element with any controller attribute. Altered INPUT take the form:

<!-- src/index.html -->
<!-- ... -->
<input class="form-control"
       type="text"
       placeholder="Amount"
       ng-model="transactions_ctrl.newTransaction.amount">
<!-- ... -->
<input type="text"
       class="form-control"
       placeholder="Description"
       ng-model="transactions_ctrl.newTransaction.description">
<!-- ... -->

It remains now add form submission process. Fortunately, this has a built-in Angular.js directive ng-submit. Form takes the form:

<!-- src/index.html -->
<form class="form-inline" ng-submit="transactions_ctrl.addTransaction()">
<!-- ... -->
</form>

Add a method addTransaction() in TransactionsCtrl :

// src/app/main/transactions.controller.js
// ...
this.addTransaction = function() {
  this.transactions.push(this.newTransaction);
  this.resetTransaction();
}
// ...

 

All is ready! Open the browser, fill in the form below, or Hit Enter-button on the form and our table is automatically updated: a new transaction appears at the bottom of the table. Note: we have not written the code that updates a table. Angular.js he understands that when the array of transactions need to be updated corresponding to the array of the html-code. This is one of the coolest features Angular.js – automatic updates and two-way communication between the html-code and application code.

Now, dear reader is invited to move from reading the tutorial to a particular practice. Here are some tasks that you can solve on their own within this sample application:

  1. Get rid of these transactions directly in the code.
  2. Sort Descending transaction Transaction date – the most recent on top than below the old one.

Forknite repository with an application and implement these tasks. All the code in this article is to commit 12aacf6 In the next article we will learn how to use the service objects and learn about dependency injection in Angular.js.

Yaroslav Golovach
y