Angular controller: $scope or VAR for non-view variables - angularjs

I know that I should keep my controllers lean & mean, but if I do need a variable which will not be reflected in the view, should I declare it in $scope. or as var?

I declare them as var if I dont need two-way binding. When you put your data into $scope, you put a watch on them (and with this put it in the angular digest cycle) and that's redundant if you dont need to use the variable in the view. Simple rule: Don't use $scope if you dont need angular to update the view with it.

Related

What is the disadvantage of using the $scope as variable in angularjs, to share $scope of a controller inside the app.run?

What is the disadvantage of using the $scope as variable in AngularJS, to share $scope of a controller inside the app.run()?
Actually I am doing that to make code generic to be called from all the controllers with same function in app.run().
The function I am using is with the
$rootScope.getUserInfo = function($scope){
$scope.userinfo = '---------';
}
where $scope is the variable that I am passing from every controller like that
$rootScope.getUserInfo($scope);
I don't think there's inherently something wrong with passing around a scope. People do this a lot in AngularJS services and it's internally done a lot, too: your created controller is passed a scope to work with.
However, I would say it's not necessary in your example to have getUserInfo to depend on a scope being passed. Why not return the user information and have the caller put it on the scope? That way, you can use it in parts of your app that don't have a scope.
Instead of using $scope, you can use var vm = this; and define everything in that controller with vm.variablename_or_funcname instead of $scope.variablename_or_funcname
And you can attach that controller in html like ng-controller = "mycontroller as vm"
More info:
https://johnpapa.net/angularjss-controller-as-and-the-vm-variable/

bindToController how to get rid of all the $scope ($scope.$on)

I'm implementing an AngularJS directive on Angular 1.4.12 using the controllerAs and bindToController "pattern" in order to have a clean controller which doesn't depend on $scope.
However I still find hard to get rid of $scope on these lines:
$scope.$on( '$destroy', function() {...} );
$scope.$on( '$stateChangeSuccess', function() {} );
Any idea how to handle this case?
Thanks
The idea behind not using $scope is to:
not pollute the HTML with variables that have no context and potentially have conflicting variable names in the same scope.
ng-model="name" VS ng-model="userController.user.name"
not pollute you javascript code by preceding every variable and
function with $scope
If you need to broadcast events or watch changes, it's perfectly fine to use $scope (especially if you have no alternative like .components in angular 1.5)
See $scope as a service provided to you by Angular just like $window or $state.
If you need it, you can use it. (but don't go and put code in there, even if you can)

$scope vs var in AngularJS

I've been using var and $scope.varname and both work fine in AngularJS. I was wondering if there was a difference between the two functionally, and what best practice was in which one to use?
Yes! $scope variables bind to the view where as var does not and is local to the function it was declared in!
var x = 3;
$scope.y = 3;
{{x}} - undefined
{{y}} - 3
The technical implications of using var and $scope have been described by #tymeJV and others. I think the next logical question answer is: When do I use either?
TL;DR - if you do not use a variable in a view (e.g. {{myVar}} ), use var.
The reason is two fold:
Encapsulation - hide state that is not necessary to the view. This will prevent unintended modifications of the variable.
Performance (prevent extra digest cycles) - Angular performs "dirty state" checking on variables. Modifying a variable that's not used in the view may cause extra digest cycles unnecessarily. In an application with a couple of ng-repeats and a bunch of watches, this can have a huge impact.
1 - $scope, is the glue between your controller and your view/model , when you are defining a variable/function to the $scope of a controller, your whole view , which this controller controls it ! , can see that variable/function . Where a pure variable just works in that controller , not even the view of that controller!
2- Every thing that has been defined to the $scope , is manupulatable from the outside of the controller , throughout the Directives , Services , your html view ... , while a pure variable is NOT;
Simply spoken - all variables you define on $scope, e.g. in your controller, are available in your html markup. in case you need a variable just inside your js functions, you can declare it with var, they are only locally available. Same with functions.
$scope bind value to the view and var is the local variable to the application.

Directive not updated after factory call

I have a custom directive that has a single attribute called content. I'm trying to pass data to this directive's attribute via an outer's controller scope variable called x. This seems to work fine by setting x equal to 'xyz' at the start of the controller, but when I make a call to a factory to pull a value to update the x variable the data isn't being reflected in the directive. I can see that $scope.x is being set to the return value from the factory within the controller, but it's not then updating the directive.
I seem to missing something somewhere. I'm guessing it's a scope problem but I'm just not seeing it. I've tried to simplify my issue into a Plunker (http://plnkr.co/edit/wsWzSTJ9VDprfTaToeHv).
Any thoughts?
Thanks
Chris
The basic problem as noted in the comments is a missing $watch in the directive controller.. the controller doesn't "know" that content variable has changed..
so adding a $watch in the controller (the directive controller!) would solve this:
$scope.$watch(function(){return $scope.content}, function(){
$scope.text = $scope.content
})
A working demo
Good luck!

how does $scope in controllers work and different ways of declaring controllers?

I am looking at some samples of how controllers work in angular and I see two ways of declaring them, one with just controller name and one with "as somename". Examples that use ng-controller = "myController" take a $scope as dependency when defining controller.
Then model is then set on the $scope, something like this
$scope.mymodel = somevalue;
Example that uses "as" syntax such as ng-controller = "MyControler as vm" never uses $scope when setting up the model but ratther assigns it to "this" and binds using {{vm.something}}.
in controller:
var vm =this;
vm.something = somevalue;
How is that working in second example? Is that new way in latest version?
Using the "as" syntax exposes your entire controller to your view. In my opinion, that is a bad practice. Although I'm not sure which one is better performance wise, but using 'this' in javascript already has plenty of issues of its own, and I don't recommend adding another meaning to 'this'. So I would stick to $scope (since that is what they're using in the docs as well).
See this topic if you want to know more context about how the 'as' syntax work: 'this' vs $scope in AngularJS controllers

Resources