7

I have two sets of code like the following

First set of Code:

var app=angular.module('demo', []);
app.controller('mainController',function(){
     this.myVar='hai';
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.22/angular.min.js"></script>
<html ng-app="demo">
<div ng-controller="mainController as mainControl">
  <p>{{mainControl.myVar}}</p>
</div>
</html>

Second Set of Code:

var app = angular.module('demo', []);
app.controller('mainController', ['$scope',
  function($scope) {
    $scope.myVar = 'hai';
  }
]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<html ng-app="demo">
<div ng-controller="mainController">
  <p>{{myVar}}</p>
</div>

</html>

I want to know the difference between this two way of declaring models to the view. Can some one please explain. I am new to Angular JS

3
  • 2
    You should probably read up on how Angular works with $scope. It is the recommended way to bind to the UI. For one, without $scope you will not $watch and therefore I wouldn't expect 2-way binding to work. Also, your snippets done seem to run for me. Commented Oct 1, 2014 at 9:46
  • Please look at this post and video thinkster.io/egghead/experimental-controller-as-syntax Commented Oct 1, 2014 at 12:28
  • THe Code is working. Commented Oct 6, 2014 at 5:11

3 Answers 3

8
  • controllerAs View Syntax: Use the controllerAs syntax over the classic controller with $scope syntax.

Why?: Controllers are constructed, "newed" up, and provide a single new instance, and the controllerAs syntax is closer to that of a JavaScript constructor than the classic $scope syntax.

Why?: It promotes the use of binding to a "dotted" object in the View (e.g. customer.name instead of name), which is more contextual, easier to read, and avoids any reference issues that may occur without "dotting".

Why?: Helps avoid using $parent calls in Views with nested controllers.

<!-- avoid -->
<div ng-controller="Customer">
  {{ name }}
</div>

<!-- recommended -->
<div ng-controller="Customer as customer">
  {{ customer.name }}
</div>
  • controllerAs Controller Syntax: Use the controllerAs syntax over the classic controller with $scope syntax.

The controllerAs syntax uses this inside controllers which gets bound to $scope

Why?: controllerAs is syntactic sugar over $scope. You can still bind to the View and still access $scope methods.

Why?: Helps avoid the temptation of using $scope methods inside a controller when it may otherwise be better to avoid them or move them to a factory. Consider using $scope in a factory, or if in a controller just when needed. For example when publishing and subscribing events using $emit, $broadcast, or $on consider moving these uses to a factory and invoke from the controller.

/* avoid */
function Customer ($scope) {
  $scope.name = {};
  $scope.sendMessage = function () { };
}
/* recommended - but see next section */
function Customer () {
  this.name = {};
  this.sendMessage = function () { };
}
  • controllerAs with vm: Use a capture variable for this when using the controllerAs syntax. Choose a consistent variable name such as vm, which stands for ViewModel.

Why?: The this keyword is contextual and when used within a function inside a controller may change its context. Capturing the context of this avoids encountering this problem.

/* avoid */
function Customer () {
  this.name = {};
  this.sendMessage = function () { };
}
/* recommended */
function Customer () {
  var vm = this;
  vm.name = {};
  vm.sendMessage = function () { };
}

Note: You can avoid any jshint warnings by placing the comment below above the line of code. /* jshint validthis: true / var vm = this; Note: When creating watches in a controller using controller as, you can watch the vm. member using the following syntax. (Create watches with caution as they add more load to the digest cycle.)

$scope.$watch('vm.title', function(current, original) {
    $log.info('vm.title was %s', original);
    $log.info('vm.title is now %s', current);
});

https://github.com/johnpapa/angularjs-styleguide#controllers

Sign up to request clarification or add additional context in comments.

Comments

2

You really shouldn't use this to declare model that bind to the UI with Angular. Your first example is very rarely seen in Angular. In my experience, even controller aliasing isn't seen that much.

The difference between the two examples is that one uses $scope while the other does not. Using $scope is fundamental to how Angular binds (and 2-way binds) data to the UI. The $scope is not just a replacement for this. $scope is inherited from parent controller $scope objects up the tree until reaching $rootScope.

So there is a tree of $scope objects that define the state of an Angular application. Each time Angular is alerted to do so (through its $digest cycle), Angular checks the values on all $scope objects in the tree. If the values have changed, Angular can rebind the UI. This is essentially how 2-way binding works.

So, using your first example will work, but will not give you many benefits of using Angular.

You can see from the example below that when a click event is fired, the data does not update as it should:

var app=angular.module('demo', []);
app.controller('mainController',function($scope){
     this.myVar='hai';
  
  
     $scope.clickMe = function() {
         this.myVar = "changed";
     }
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.22/angular.min.js"></script>
<html ng-app="demo">
<div ng-controller="mainController as mainControl">
  <p>{{mainControl.myVar}}</p>
  <button ng-click="clickMe()">click me</button>
</div>
</html>

1 Comment

This example is not valid as an argument. First of all, you are using this keyword inside the clickMe funcion, which is another context. You should capture this as soon as the controller starts to some variable and use it. Then it would work, see Jack's answer to understand.
0

var app=angular.module('demo', []);
app.controller('mainController',function($scope){
     this.myVar='hai';
  
  
     this.clickMe = function() {
         this.myVar = "changed";
     }
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.22/angular.min.js"></script>
<html ng-app="demo">
<div ng-controller="mainController as mainControl">
  <p>{{mainControl.myVar}}</p>
  <button ng-click="mainControl.clickMe()">click me</button>
</div>
</html>

The above code will work and also it is doing a Two Way data binding. So by declaring functions and variables inside the controller using "this" , I can specifically use that variables and functions only within that functions rather than by using $scope the tree will grow on.In this case i can reduce the memory size of the variables and functions . Can some one please correct me if i am wrong

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.