I have a controller where the $scope object has been used to store methods and values that are only used locally within the same controller. There is a lot of this going on:
$scope.foo = 'something';
$scope.bar = 'something else';
... and so on. None of these values are used within the view. My question is does polluting the $scope object affect performance? Is it a good idea to clean this up so only values and methods needed for the view are contained in the $scope object?
Yes, Polluting $scope does affect performance, but its depends your scope has multiple watchers which are frequently changing then that will create a more overhead cost. Refer this answer which has covered same point
For avoiding this situation I'd suggest you to do good re-factoring of code
Handle all the logic in controller whenever required otherwise do separate a logic by making good use of each component.
Move common method(logic) to service/factory/provider which is used in multiple place, so that it would be sharable.
If some value are fixed, they are not gonna change then move them to constant/value
Whenever you feel like you have same logic which needs to be keep in $scope it self then move that logic to common controller. When required you could inject in your current controller scope using $controller injector
Also refer Understanding Of Scope for clear understanding of use of scope
Related
I'm working on some code that references $scope.model. So my understanding is that in angular the $scope essentially represents the model anyway.
In the code I'm working on certain properties have been added to a $scope.model. So is adding members under $scope.model a recognised (or sensible) angular practice (since 'model' seems to essentially be an arbitrary member that someone has simply decided to add to the scope). If using a $scope.model is a useful practice, when should it be used? There don't seem to be online resources that mention $scope.model.
actually every controller had associated $scope object (contain some properties) when you use $scope.model you are setting a model property or a function behaviour and make it available to the view (among other $scope properties in most cases you dont have to worry about them)
you can learn more about the $scope and it properties and life cycle in angularJS documentation its a usefull resource
https://docs.angularjs.org/guide/scope
Is it advisable to store data in $rootScope.
I have a cordova app which uses sensor data which is coming every 100ms. For me to use that data in multiple controller I am using $rootScope.sensorData variable which is being refreshed every 100ms. Is it alright to use it this way? Is there a better way to do it?
Thank you
You can store it in factory. In AngularJS factory is singleton, so only instance is created.
myApp.factory('SensorSrv', function SensorSrv() {
var sensorData;
return {
setData: setData,
getData: getData
};
function setData(data) {
sensorData = data;
}
function getData() {
return sensorData;
}
});
You can also user local-storage if you want to persist the data.
I think this is not good idea to use $rootScope in entire code logic , There are lot of reasons behind that ... Instead of that you can create code login in services it is more flexible ... and also you can see this link
Best practice for using $rootscope in an Angularjs application?
From the Official Docs:
$rootScope exists, but it can be used for evil
Scopes in Angular form a hierarchy, prototypally inheriting from a root scope at the top of the tree. Usually this can be ignored, since most views have a controller, and therefore a scope, of their own.
Occasionally there are pieces of data that you want to make global to the whole app. For these, you can inject $rootScope and set values on it like any other scope. Since the scopes inherit from the root scope, these values will be available to the expressions attached to directives like ng-show just like values on your local $scope.
Of course, global state sucks and you should use $rootScope sparingly, like you would (hopefully) use with global variables in any language. In particular, don't use it for code, only data. If you're tempted to put a function on $rootScope, it's almost always better to put it in a service that can be injected where it's needed, and more easily tested.
Conversely, don't create a service whose only purpose in life is to store and return bits of data.
--AngularJS Miscellaneous FAQ
I recommend using app.value app.value('test', 20);
Because by using $rootScope you are exposing that value to all the services which might be a security threat. By using value you can make sure where do you want to use that variable according to your requirement.
If the right way to share data between controllers are using factory/service, what is the purpose of the $rootScope?
$rootScope exists, but it can be used for evil
Scopes in Angular form a hierarchy, prototypally inheriting from a root scope at the top of the tree. Usually this can be ignored, since most views have a controller, and therefore a scope, of their own.
Occasionally there are pieces of data that you want to make global to the whole app. For these, you can inject $rootScope and set values on it like any other scope. Since the scopes inherit from the root scope, these values will be available to the expressions attached to directives like ng-show just like values on your local $scope.
Of course, global state sucks and you should use $rootScope sparingly, like you would (hopefully) use with global variables in any language. In particular, don't use it for code, only data. If you're tempted to put a function on $rootScope, it's almost always better to put it in a service that can be injected where it's needed, and more easily tested.
Conversely, don't create a service whose only purpose in life is to store and return bits of data.
-- AngularJS FAQ
As per my understanding.
you can use $rootScope in multiple places .
global settings defined in factory and then in view you can update as per your condition. f.x layout manipulation
you can assigned $state on run.
you can handle error ($rootScope.$on(...)
I hope this will help.
Thanks
I would like to persuade my co-worker that it is a better approach to use component directives than to use $rootScope everywhere. I need arguments against his ones because he is very stubborn and a very good speaker (which I am not). He thinks that $rootScope prevents spaghetti code. This week I have refactored the project and there are no more spaghetti but I don't want him to rework everything to $rootScope.
Please tell me about problems and issues that can arise when using $rootScope. Thank you.
EDIT
Are there any security issues with $rootScope?
EDIT 2
My friend came with this construct and wants to put it in every component:
function Controller(service, $rootScope, $scope) {
var vm = this;
$scope.a = $rootScope.a;
$scope.b = $rootScope.b;
$scope.c = $rootScope.c;
$rootScope.$watch('mapLoaded', function () {
$scope.a = $rootScope.a;
$scope.b = $rootScope.b;
$scope.c = $rootScope.c;
}, true);
Would the issue of destroying scopes and removing wathces that #charlietfl described in comments appear? I am definitelly not gonna let him code like this but I need the arguments against it. Thanks again.
$rootScope exists, but it can be used for evil
Scopes in Angular form a hierarchy, prototypally inheriting from a root scope at the top of the tree. Usually this can be ignored, since most views have a controller, and therefore a scope, of their own.
Occasionally there are pieces of data that you want to make global to the whole app. For these, you can inject $rootScope and set values on it like any other scope. Since the scopes inherit from the root scope, these values will be available to the expressions attached to directives like ng-show just like values on your local $scope.
Of course, global state sucks and you should use $rootScope sparingly, like you would (hopefully) use with global variables in any language. In particular, don't use it for code, only data. If you're tempted to put a function on $rootScope, it's almost always better to put it in a service that can be injected where it's needed, and more easily tested.
Conversely, don't create a service whose only purpose in life is to store and return bits of data.
-- AngularJS FAQ
I will response myself to Edit 2 citing this:
Using $watch means whenever you read this code in the future you’ll
have to consider whether it’s being triggered by something else, too.
Use case
For use in a form, I created a directive that tracks changes in an array. It allows changes to be reverted and deletions and additions to be stored separately. It allows for an array (one to many mapping in the database) to be updated incrementally (rather than requiring the server to either diff, or rewrite the entire list).
Problem?
My question is about the way I expose the functionality to the controller's scope. I currently use an two-way databound attribute on the directive's scope. This works, and it seems reliable (of course you can easily break it by reassigning the scope's value, but intentionally you can break anything).
Code
You can see this plunk to see this in action. It allows methods on the directive's controller to be called from the view and the view's controller. (I am using the directive controller intentionally because that's what I do in my actual code for the directive to directive communication, but this could also just be placed in the linking function.)
Question
Is this way of doing it bad design? Am I completely throwing AngularJS out of the window now and hacking in my own code. Are there any better ways to expose functions from a directive (keep in mind that there'll be multiple of these in a single form).
It's very easy to pass in my-attribute="someFunction()" to have the directive be a consumer of the view controller. I can't find a better way to do the opposite and have the view controller consume from the directive.
Alternative?
I've been thinking about using a service here, in which the service will provide an object that is instanciated in the view, passed to the directive, and have the directive blurp out it's results to that object. Then in turn have the view controller consume the information from that service's object. Would this be a better approach?
There's nothing wrong with your approach. In fact built-in angular directives such as ng-form use this approach to store the controller in the scope (see the name property of ng-form) http://docs.angularjs.org/api/ng.directive:ngForm
For more re-usability though I would put the api methods on the controller and then put the controller itself in the api:
this.getChanges = function () {};
this.resetChanges = function(){};
$scope.api = this;
In directives, the main purpose of the controller is to serve as an api for other directives (if you didn't need an api for other directives you could just do everything in the link function). Doing it this way ensures the api is available both on the scope as well as to any directive that 'requires' the oneToMany directive.