Tuesday, January 20, 2015

AngularJS Tip 3 - JavaScript Properties in AngularJS

One of the frequent questions that people ask me is how to connect data from the business service to the controller, so it will be easy to bind it to HTML tags.

Option 1:

function UserCtrl(userBL){
    this._bl = userBL;
    this.name    = userBL.name;
    this.address = userBL.address; // address is an object.
}

<div ng-controller="UserCtrl as vm">

    <input type="text" ng-model="vm.name" placeholder="name"><br>

    <input type="text" ng-model="vm.address.street" placeholder="street"><br>

    <input type="text" ng-model="vm.address.house" placeholder="house"><br>    

    <br>

    name : {{vm._bl.name}}<br>
    Address : {{vm._bl.address | json }}<br>
</div>

JavaScript copies by value primitive types, so it copies the value of “userBL.name” to “this.name”. Because of that, the ng-model connects the input value to “this.name” but the “userBl.name” is not updated when the “this.name” is changed.

JavaScript copies by value the reference when it is an object type. Because of that, the “userBL.address” and the “this.address” is the same object, so when the ng-model connects the input value to the “this.address” it also updates the “userBL.address”.

Note: If you assign new object to the “userBL.address”, you lose the binding because the “this.address” points to an old object, meaning the binding stops updating the “userBL.address”.

userBL.address = {strees:’abc’, house: 1};
 
A JavaScript properties came to rescue, see option 2.
 
Option 2:
 
function UserCtrl(userBL){
    this._bl = userBL;
    Object.defineProperties(this,{
       name : {
           get : function(){
               return userBL.name;
           },
           set : function(value){
               userBL.name = value;
           }
       },
       address : {
           get : function(){
               return userBL.address;
           },
           set : function(value){
               userBL.address = value;
           }
       }
    });
}
 
With JavaScript Properties the binding works on “userBL”. Which means no more copy by value of reference. We can use the same approach between a BL and a storage service (userDTO). 
 
Option 3:
 
(function (angular) {
    ‘use strict’;
    //////////////// AngularJS //////////////
    var mi = angular.module(‘myApp’, [])
    .factory(‘userBL’,blFactory)
    .factory(‘userDTO’,dtoFactory)
    .controller(‘UserCtrl’,UserCtrl);
    //////////////// JavaScript //////////////
    function dtoFactory($log){
        return {
            name: ‘bl-name’,
            address: {
                street: ‘abc’,
                house: 47
            }
        };
    }

    function blFactory($log,userDTO){
        var blUser = Object.defineProperties({},{
            name : {
                get: function(){
                    return userDTO.name;
                },
                set : function(value){
                    userDTO.name = value;
                }
            },

            address : {
                get: function(){
                    return userDTO.address;
                },
                set : function(value){
                    userDTO.address = value;
                }
            }
        });

        return blUser;
    }



    function UserCtrl(userBL){
        this._bl = userBL;
        Object.defineProperties(this,{
           name : {
               get : function(){
                   return userBL.name;
               },
               set : function(value){
                   userBL.name = value;
               }
           },

           address : {
               get : function(){
                   return userBL.address;
               },
               set : function(value){
                   userBL.address = value;
               }
           }
        });

    }   

})(angular);
 
 
We can write a helper function for creating JavaScript property more easily.

function createProperty(source,wrapper,property){
    Object.defineProperty(wrapper,property,{
        get: function(){
            return source[property];
        },
        set : function(value){
            source[property] = value;
        }
    })
}
 
Now the controller look like this:
 
function UserCtrl(userBL){
    this._bl = userBL;
    createProperty(userBL,this,’name’);
    createProperty(userBL,this,’address’);
}
 

Note: I wrote the properties on a 'this' object. We can do the same on a $scope object or to write the properties on a “UserCtrl.prototype”. This way we don’t duplicate the get and set functions every time we create a UserCtrl instance.

function UserCtrl (userBL){
    this._bl = userBL;

    createProperty(userBL,UserCtrl.prototype,'name');
    createProperty(userBL,UserCtrl.prototype,'address');
}

Last note: ngModelOptions
AngularJS 1.3 has a new directive called ng-model-options. This directive can bind throw setter and getter.

<input type="text" ng-model="vm.name" ng-model-options="{getterSetter:true}">

See documentations. I believe that working with JavaScript Properties is a better way.


I would be happy to receive feedback J

Monday, June 23, 2014

Become an expert in AngularJS with this four days in-depth training course.

This course will teach you the AngularJS fundamentals and the internal. The course will cover directives, binding, filters, ngRepeat, testing, isolate scopes and much more, with real-world examples. ng-course, the best course in Israel.

Dates: 15-17,21/7/2014

ברוכים הבאים לאתר ng-course. אתר זה מרכז את כל החומרים שמועברים בקורס שלי, מצגות, דוגמאות ומאמרים. קורס ng-course הוא לא קורס רגיל על Angular, קורס זה מבוסס על הנסיון העשיר שלי בעשרות פרוייקטים ב- AngularJS שהיתי מעורב בהם. בקורס אני מלמד איך משתמשים באנגולר וגם איך הוא עובד מ"תחת למנוע". ידע זה יאפשר לכם להבין איך אפשר לשפר ולהרחיב את אנגולר לצרכים שלכם. הקורס הבא נפתח ב-15 ליולי, לחץ כאןלפרטים.

Trainer


Eyal Vardi is the CTO and CO-CEO of E4D Solutions LTD. Eyal was nominated as MVP (Microsoft Most Valuable Professional) for 9 years is a row. The title was given to him based on the contribution to the developers and technical community through lectures, conferences, open house events, Blog posts and free tools. Eyal is involved in wide range of cutting edge industry projects, specializing in architecture, design and development of advanced projects and products.

My Tools