Angularjs directive

Directives are the most important feature of AngularJS . Before we jump into how to create custom directive, first to understand the relationship between directive Scope and controllers is very important to help your create custom directives.

In angularjs, directive sit inside controllers, so when you create a custom directive, you must first create an angularjs module and controller first.

When you create a directive, angularjs provide 3 different scope for your to use:

Shared scope when you create a directive don’t specify the scope then it will be shared scope.So your controller and your directive has the same scope, like in c# field, the controller and the directive have point it point to the same object.Create shared scope you must be very careful, because the directive could override the controller scopes.

//shared scope example
angular.module('app', []);

angular.module('app').controller('mainCtrl', function($scope) {
  $scope.Todo = {
    title: 'your title',
    address: 'your address',
    description: 'your description'

});

angular.module('app').directive('toDoList', function() {
  return {// in here I didn't specify the scope, so it will be shared scope
    templateUrl: "todoList.html",
    restrict: "E"
  }
})

////event without define the scope in here, but the directive already share the 
//mainCtrol scope here
//toDolist.html
Title:{{title}}
Address:{{address}}
Description: {{description}}

Inherited scope when you create a directive return scope:true then it will create a inherited scope, so the parent scope(controller scope) will visible in the child scope( directive scope), but the  directive can’t override the parent scope. for example if you have scope.message = “parent message”; in the directive you create a scope.message = “child messages” it won’t override the parent scope, in there view if you use {{messages}} output is parent message, but if you use shared scope, in the directive template the output will be {{child messages}}

//shared scope example
angular.module('app', []);

angular.module('app').controller('mainCtrl', function($scope) {
  $scope.message = "parent message";
);

angular.module('app').directive('messagesView', function() {
  return {
    templateUrl: "messagesView.html",
    restrict: "E",
    scope:true,  // this is make the directive scope inherit from the mainCtrl
    controller:function($scope){
      $scope.message = "child message"; 

 } } })
//messagesView.html
{{message}} // output will be parent message 

Isolated scope: it allow the developer to encapsulate the data to your custom directive use only.

angular.module('app').directive('removeTodo', function() {
  return {
    restrict: 'E',
    templateUrl: 'removeTodo.html',
    scope: {
      todos: '=' //todos is only visible in your directive scope
    },
    controller: function($scope) {
      $scope.removeItem = function(todo) {
        var idx = $scope.data.indexOf(todo);
        if(idx > -1) {
          $scope.data.todo.splice(idx, 1);
        }
      }
      
    }
  }
})

And attach the whole angularjs directive structionangularjs-directive

Angularjs Service — Value and Constant Services

Value Services

  • Shorthand for factory with no parameters
  • Cannot be injected into a module configuration function
  • Can be overridden by an AngularJS decorator

Example using value

 angular.module('app')
        .value('clientId', 'a12345654321x');

Constant Services

  • Simply registers service with injector, no factory/provider calls
  • Can be injected into a module configuration function
  • Cannot be overridden by an AngularJSdecorator

Example

angular.module('app')
        .constant('constants', {
            APP_TITLE: 'My App',
            APP_DESCRIPTION: 'Description here.',
            APP_VERSION: '0.0.1'
        });

	

ANGULARJS SERVICES – Factory and Services

Using the factory function on the provide service is usually a much simpler option than using provider, if you don’t need to configure the underlying provider object. The snippet of code here is the Angular source code for the factory function.

function factory(name, factoryFn, enforce) { 
	return provider(name, { 
		$get: enforce !== false ? enforceReturnValue(name, factoryFn) : factoryFn 
		}); 
	}

You can see that all it really does is call the provider function and assign the function you pass to the factory function as the value of the get property on the provider.

Internally, it creates and passes the parameter name, enforce, just as a safety check to make sure the function passed to it actually returns an object. To use the factory function, you just pass it a name as the first parameter, like the provider function, and the second parameter is a function that will return an object that represents the service instance. If you don’t need to configure the provider, like previous post sample demo code, then using the factory function will be a much simpler and readable way to create your services.

The next service creation function we’ll look at is actually named service. It’s just a very thin wrapper around the factory function we just saw. The only difference is that the function you passed to the service method will be treated as a constructor function and called with the JavaScript “new” operator.

The snippet here is the Angular source code for the service function.

	function service(name, constructor) { 
	  return factory(name, ['$injector', function($injector) {  
	   return $injector.instantiate(constructor); 
	   }]);
	 }

It uses the instantiate method of the injector to call the function you pass to the service method. The instantiate method will then use the “new” operator to execute the function that creates the service. You would use the service method instead of the factory method if you specifically needed your function to be treated as a constructor and called with the “new” operator. There are several reasons why you may want that behavior. One is if you have defined an inheritance hierarchy in your code. Creating an instance with “new” will make sure that your instantiated object properly inherits from its prototypes.

Here is the example you must use the services instead of factory.

angular.module('app')
        .service('logger', MyLogger);

    function LoggerBase() { }

    LoggerBase.prototype.output = function(message) {
        console.log('LoggerBase: ' + message);
    };

    function MyLogger() {

        LoggerBase.call(this);

        this.log = function(obj) {
            console.log('Book: ' + obj.name);
        }
    }

    MyLogger.prototype = Object.create(LoggerBase.prototype);

only now I can use the output function, but using factory it won’t.

 app.config(['$logProvider',  function ( $logProvider) {
        $logProvider.output('what ever here!');

to be continue……..

AngularJs Services – Provider

Try to help reader to understanding of Angular service, and the confidence to choose the right technique when come to use it .

There are five functions you can use to create an Angular service. All of these functions may be called on the built-in provide service. All of them are also exposed on the module object as a convenience. The most fundamental service creation function is the provider function. Creating services with it allows you to explicitly create a configurable provider object. The provider knows how to create the resulting service. The remaining four functions all internally call the provider function.

Now start with the lower provider services, here is the example code for using the angularjs provider service:

app.provider('myApp', [function () {

        var includeVersion = false;
        this.setIncludeVersion = function (value) {
            includeVersion = value;
        };

        this.$get = function () {
            var appName = 'My first App";
            var version = '0.0.1';
            if (includeVersion) {
                appName += ' ' + version;
            }
            var appDesc = 'here is some description';
            return {
                appName: appName,
                appDesc: appDesc
            };
        };

    }]);

See in here you could pass a parameter to decided some basic setting, just like website have a web.config file, so the app in the client side also have their own config file.
Be aware of when you use the provider function the angularjs will automatic add the Provider to it, so when you use it need use the name with myAppProvider.

   app.config(['myAppProvider', function (bookingAppProvider) {
        
        myAppProvider.setIncludeVersion(true);
        
        ..................

    }]);

to be continue….

Example test your controller, Nunit test

for you home controller:

using System.Web.Mvc;

namespace WestBanking.Controllers
{
    public class HomeController : Controller
    {
       

        public ActionResult Index()
        {
            return Redirect("http://netbank.test.com");
        }
    }
}

here is your test

using WestBanking.Controllers;
using NUnit.Framework;
using TestStack.FluentMVCTesting;

namespace WestBanking.ControllerTests   
{
    [TestFixture]
    public class HomeControllerTests
    {
        [Test]
        public void ShouldRedirect()
        {
            var sut = new HomeController();

            sut.WithCallTo(x => x.Index()).ShouldRedirectTo("http://netbank.test.com");
        }
    }
}

Example of using moq in your nunit test

When you do unit test, we won’t use the real server to do the test, the moq package could help us do the dependence inject.

here is the sample example how to use moq to mock your inject classes

using WestBanking.Models;
using Moq;
using NUnit.Framework;

namespace BankingSite.UnitTests
{
    [TestFixture]
    public class LoanApplicationScorerTests
    {
        [Test]
        public void ShouldDecline_TooYoung()
        {
            var fakeCreditChecker = new Mock();            
            
            //go pass the CheckCredit method
            fakeCreditChecker.Setup(
                x => x.CheckCredit(It.IsAny<int>())
                .Returns(true);
            //inject the fake instance here
            var sut = new LoanApplicationScorer(fakeCreditChecker.Object);

            var application = new LoanApplication
                              {
                                  Age = 21
                              };

            sut.ScoreApplication(application);

            Assert.That(application.IsAccepted, Is.False);
        }


        [Test]
        public void ShouldOK_Young_Wealthy()
        {
            var fakeCreditChecker = new Mock();

            fakeCreditChecker.Setup(
                x => x.CheckCreditHistory(It.IsAny<int>())
                .Returns(true);

            var sut = new LoanApplicationScorer(fakeCreditChecker.Object);

            var application = new LoanApplication
            {
                AnnualIncome = 1500000.01m,
                Age = 21
            };

            sut.ScoreApplication(application);

            Assert.That(application.IsAccepted, Is.True);
        }


        [Test]
        public void ShouldDecline_NotYoung_PoorCredit()
        {
             //create a instance of fake class
            var fakeCreditHistoryChecker = new Mock();

            fakeCreditChecker.Setup(
                x => x.CheckCreditHistory(It.IsAny<int>()))
                .Returns(false);

            var sut = new LoanApplicationScorer(fakeCreditHistoryChecker.Object);

            var application = new LoanApplication
            {
                AnnualIncome = 30000.01m,
                Age = 30
            };

            sut.ScoreApplication(application);

            Assert.That(application.IsAccepted, Is.False);
        }


    }
}

Write your first Unit test – Test your model

For example you have very simple code like this:

namespace WestBanking.Models
{
    public class CheckCredit: ICreditChecker
    {
        public bool IsCreditWorthy(int credit)
        {
            // Simulate actual credit check

            if (credit<200)
            {
                return false;
            }

            return true;
        }
    }
}

For the test code:

using WestBank.Models;
using NUnit.Framework;

namespace BankingSite.UnitTests
{
    [TestFixture]
    public class CreditCheckerTests
    {
        [Test]
        public void BadCredit()
        {
            //sut: system under test
            var sut = new CreditChecker();

            var isCreditWorthy = sut.IsCreditWorthy(100);

            Assert.That(isCreditWorthy, Is.False);
        }

        [Test]
        public void GoodCredit()
        {
            var sut = new CreditChecker();

            var isCreditWorthy = sut.IsCreditWorthy(1000);

            Assert.That(isCreditWorthy, Is.True);
        }
    }
}

Nunit test in Visio Studio – Set up – To be continue

Recently my job need write all the unit test for my project and I haven’t done this before, and I like share my experience here, and hope that could help someone else.

First, Install an test runner  that will help you do the test in Visual Studio.

Tool > extension and updates > search online> nunit test adapter

nunit test

Second, create an test project

Third, Open the PM console, install some useful packages:

Nunit

Moq

TestStack.FluentMVCTesting

Truth in Javascript and simple example using in angularjs

Javascript is loose language and understand the truth is very help you to write javascript code. Here it is:

var num = 0;
var myObj1 = undefine;
var myObj2 = null;
var myObj3 = {};
var myStr = "";
if(num) // false
if(myObj1) // false
if(myObj2) //false
if(myStr) //false
if(myObj3) // true

Very simple and common used in angularjs


<div ng-show="myObj3"></div> // will show

<div ng-show="myStr" class="ng-hide"></div> // will hide

The architecture of real live AngularJS — Get start with angularJs — Part 2

A good project should has a good architecture, and in angularjs is very easy to modular your projects. And also your project will be easy to extend it.

For example like this:

(function () {
    "use strict";
   
   // app.js
    var app = angular.module("productManagement",
                            ["services",
                             "productResource"]);
}());

//this is services.js
(function () {
    "use strict";
    angular
        .module("services",
                ["$http"])
}());
 

//this is my productResource.js
(function () {
    "use strict";
    angular
        .module("services")
        .factory("productResource",
                ["$http",
                 productResource]);

    function productResource($http) {
        //url could be external or internal
        return $http("/api/products/:productId")
    }
}());

So every javascript file just has few lines. And it separate the angular project to three modules, the main moudule is the “productManagement” and it has two dependants are “services” and “productResource”.

I came from C# background, so I like write code also follow the rule  single responsibility and dependency inversion.

It is much easy to read and extensible.

Full stack developer

Follow

Get every new post delivered to your Inbox.

Join 153 other followers