AngularJs "controller as" syntax - clarification?

Solution 1:

There are several things about it.

Some people don't like the $scope syntax (don't ask me why). They say that they could just use this. That was one of the goals.

Making it clear where a property comes from is really useful too.

You can nest controllers and when reading the html it is pretty clear where every property comes.

You can also avoid some of the dot rule problems.

For example, having two controllers, both with the same name 'name', You can do this:

<body ng-controller="ParentCtrl">
    <input ng-model="name" /> {{name}}

    <div ng-controller="ChildCtrl">
        <input ng-model="name" /> {{name}} - {{$parent.name}}
    </div>
</body>

You can modify both parent and child, no problem about that. But you need to use $parent to see the parent's name, because you shadowed it in your child controller. In massive html code $parent could be problematic, you don't know where that name comes from.

With controller as you can do:

<body ng-controller="ParentCtrl as parent">
    <input ng-model="parent.name" /> {{parent.name}}

    <div ng-controller="ChildCtrl as child">
      <input ng-model="child.name" /> {{child.name}} - {{parent.name}}
    </div>
</body>

Same example, but it is much much clearer to read.

  • $scope plunker
  • controller as plunker

Solution 2:

The main advantage with controller as syntax I see is that you can work with controllers as classes, not just some $scope-decorating functions, and take advantage of inheritence. I often run into a situation when there's a functionality which is very similar to a number of controllers, and the most obvious thing to do is to create a BaseController class and inherit from it.

Even though there's is $scope inheritence, which partially solves this problem, some folks prefer to write code in a more OOP manner, which in my opinion, makes the code easier to reason about and test.

Here's a fiddle to demonstrate: http://jsfiddle.net/HB7LU/5796/

Solution 3:

I believe one particular advantage is clear when you have nested scopes. It will now be completely clear exactly what scope a property reference comes from.

Solution 4:

Source

Difference between Creating a controller using the $scope object and Using the “controller as” syntax and vm

Creating a controller using the $scope object

Usually we create a controller using the $scope object as shown in the listing below:

myApp.controller("AddController", function ($scope) {



    $scope.number1;

    $scope.number2;

    $scope.result;

    $scope.add = function () {

        $scope.result = $scope.number1 + $scope.number2;

    }

});

Above we are creating the AddController with three variables and one behaviour, using the $scope object controller and view, which talk to each other. The $scope object is used to pass data and behaviour to the view. It glues the view and controller together.

Essentially the $scope object performs the following tasks:

  1. Pass data from the controller to the view

  2. Pass behaviour from the controller to the view

  3. Glues the controller and view together

  4. The $scope object gets modified when a view changes and a view gets modified when the properties of the $scope object change

We attach properties to a $scope object to pass data and behaviour to the view. Before using the $scope object in the controller, we need to pass it in the controller function as dependencies.

Using the “controller as” syntax and vm

We can rewrite the above controller using the controller as syntax and the vm variable as shown in the listing below:

myApp.controller("AddVMController", function () {

    var vm = this;

    vm.number1 = undefined;

    vm.number2=undefined;

    vm.result =undefined;

    vm.add = function () {

        vm.result = vm.number1 + vm.number2;

    }

});

Essentially we are assigning this to a variable vm and then attaching a property and behaviour to that. On the view we can access the AddVmController using controller as syntax. This is shown in the listing below:

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

            <input ng-model="vm.number1" type="number" />

            <input ng-model="vm.number2" type="number" />

            <button class="btn btn-default" ng-click="vm.add()">Add</button>

            <h3>{{vm.result}}</h3>

  </div>

Ofcourse we can use another name than “vm” in the controller as syntax. Under the hood, AngularJS creates the $scope object and attaches the properties and behaviour. However by using the controller as syntax, the code is very clean at the controller and only the alias name is visible on the view.

Here are some steps to use the controller as syntax:

  1. Create a controller without $scope object.

  2. Assign this to a local variable. I preferred variable name as vm, you can choose any name of your choice.

  3. Attach data and behaviour to the vm variable.

  4. On the view, give an alias to the controller using the controller as syntax.

  5. You can give any name to the alias. I prefer to use vm unless I’m not working with nested controllers.

In creating the controller, there are no direct advantages or disadvantages of using the $scope object approach or the controller as syntax. It is purely a matter of choice, however, using the controller as syntax makes the controller’s JavaScript code more readable and prevents any issues related to this context.

Nested controllers in $scope object approach

We have two controllers as shown in the listing below:

myApp.controller("ParentController", function ($scope) {



    $scope.name = "DJ";

    $scope.age = 32;

});

myApp.controller("ChildController", function ($scope) {



    $scope.age = 22;

    $scope.country = "India";



});

The property “age” is inside both controllers, and on the view these two controllers can be nested as shown in the listing below:

<div ng-controller="ParentController">



            <h2>Name :{{name}} </h2>

            <h3>Age:{{age}}</h3>



             <div ng-controller="ChildController">

                    <h2>Parent Name :{{name}} </h2>

                    <h3>Parent Age:{{$parent.age}}</h3>

                    <h3>Child Age:{{age}}</h3>

                    <h3>Country:{{country}}</h3>

             </div>

        </div>

As you see, to access the age property of the parent controller we are using the $parent.age. Context separation is not very clear here. But using the controller as syntax, we can work with nested controllers in a more elegant way. Let’s say we have controllers as shown in the listing below:

myApp.controller("ParentVMController", function () {

    var vm = this;

    vm.name = "DJ";

    vm.age = 32;

});

myApp.controller("ChildVMController", function () {

    var vm = this;

    vm.age = 22;

    vm.country = "India";



});

On the view these two controllers can be nested as shown in the listing below:

<div ng-controller="ParentVMController as parent">



            <h2>Name :{{parent.name}} </h2>

            <h3>Age:{{parent.age}}</h3>



            <div ng-controller="ChildVMController as child">

                <h2>Parent Name :{{parent.name}} </h2>

                <h3>Parent Age:{{parent.age}}</h3>

                <h3>Child Age:{{child.age}}</h3>

                <h3>Country:{{child.country}}</h3>

            </div>

 </div>

In the controller as syntax, we have more readable code and the parent property can be accessed using the alias name of the parent controller instead of using the $parent syntax.

I will conclude this post by saying that it’s purely your choice whether you want to use the controller as syntax or the $scope object. There is no huge advantage or disadvantage to either, simply that the controller as syntax you have control on the context is a bit easier to work with, given the clear separation in the nested controllers on the view.

Solution 5:

I find the main advantage is a more intuitive api since the methods/properties are associated with the controller instance directly and not the scope object. Basically, with the old approach, the controller becomes just a decorate for building up the scope object.

Here are some more info on this: http://www.syntaxsuccess.com/viewarticle/551798f20c5f3f3c0ffcc9ff