AngularJS $scope variable - angularjs

I have been start learning AngularJS 1.4.7 and I can't understand completely the $scope variables.
Is this a variable inside a Angular controller "like" public variables inside a PHP class?
For example:
I have 2 functions function1(), function2() in HomeCtrl.js and a $scope.img = null; variable, and 2 ng-click event in template file to call these functions.
On ng-cick event i call the function1 and set the value of $scope.url to somethig
Thereafter i call the function2 and console.log($.scope.url) it retutn null. Null is the initialized value of this varaiable.
I'v just set the value of $scope.url in function1 and inside function2 value of variabel is null, why?
I have no idea why happening this.

scope is instance of controller.
When you declare a controller , scope will be avaiable there.
You can access scope through out that controller.
That's why when you change on place in a controller , change will be reflect everywhere in that scope.

Do you literally call $.scope.url? Then that's a problem, it should be $scope.url, no dot between "$" and "scope".
Scope variables have nothing to do with variables accessibility concept (public/private/protected/etc).
They are those "magic" variables, which can be placed inside templates using expressions, which allows data-binding in Angular, i.e., your html with that "magic" scope variables, gets automatically updated by angular, when you just change their values inside your controller, like in that callback function for ng-click. (Actually it's not that easy, here we come to $watch and $digest, but if you are not writing your custom directives, and not mixing, for example, jQuery code with Angular code, you may not think about it for now).
Two-side data-binding, automatic html updates - that's the main point of $scope and $scope variables.
Scope is not and instance of a controller, they are different Angular entities.

Related

When do we need to manually $watch a scope variable in angular

Like the title says, I wonder when the scope variable can not be auto watched? Is that correct that all the scope variable that not specified in template should be manually watched if I want to monitor their value changing?
Thanks
You do not need to $watch any variables or scope properties unless you would like to be notified when they are changed.
Angular implicitly places a $watch on expressions referenced in templates, i.e. {{ x + y }} would place a watch on the result of $scope.x + $scope.y. When these watchers fire, Angular knows to update the view.
All the binded variables are watched by Angular, you don't need to say that you want to watch them, but not all scope variables are watched by Angular.
Watching a variable means that you are gonna be notified when the value of the variable changes. For example, you could show a pop-up when the total is greater than $10. Then you watch the total variable and you perform the action (showing the pop-up).
You can read this question and learn more about watch and Angular: How do I use $scope.$watch and $scope.$apply in AngularJS?

Why directive has scope?

As far as I know that basically scope is an instance of a controller.
Every time I declare a controller scope will be available for that controller.
But then why directive has scope in link function ?
I didn't declare any controller for the directive.
Then why link function has scope ? Any Idea ?
From the doc:
scope:
The scope to be used by the directive for registering watches.
You may also be interested to see the differences between $scope and scope.
All directives have a scope associated with them. They use this scope for accessing data/methods inside the template and link function. By default, unless explicitly set, directives don’t create their own scope. Therefore, directives use their parent scope ( usually a controller ) as their own.
However, AngularJS allows us to change the default scope of directives by passing a configuration object known as directive definition object. A directive definition object –– let’s call it as DDO –– is a simple JavaScript object used for configuring the directive’s behaviour,template..etc. Check out AngularJS docs about DDO.
So, we can use scope inside linking function to work with parent scope, child scope or isolated scope.
You may visit this for detailed information about scope inside directive.
You can share the data between controller and linking function.
Sometimes we would like to access that same data in both controller and link functions in Angular directive. Usually we add this data to the scope object. This has certain problems, for example exposing it to any child scope. Add the shared properties to the controller instance itself and access in the link function.
You may also be interested in what is need of link function?
A directive is Angular's way of defining 'components': you specify how its markup looks and how it behaves before, during and after being rendered. The link functions allow you to hook up events to the DOM element before or after it gets 'linked' (see also: pre-link and post-link methods). When these events are fired you might want to change some of the variables within the scope, and that's why you have access to it within the link functions.

Adding value to the scope outside the controller method

I am wondering how I can add a value to the scope from a function outside the controller. I have a series of functions in my controller file, which I would like to keep it separately outside a controller method, so that it can be accessed by different controllers. When the last function gets the value, I want to add it to the scope. Can anybody give me some input into this issue. Thanks
Angular $scope is not supposed to be accessed from outside. Use service/factory/provider to share data between controllers.
Say, define a factory with get/set functions. set the value in some controller and get it from somewhere else. $scope is not supposed to be passed around.

Angular JS function use $scope or not

According to the Angular docs:
Scope is the glue between application controller and the view. During the template linking phase the directives set up $watch expressions on the scope. The $watch allows the directives to be notified of property changes, which allows the directive to render the updated value to the DOM.
Now my Question is : if my function is not connected to the view, should we use $scope or not?
I assume that you mean if you should do $scope.functionName = function(), even if the function isn't connected to the view.
No you shouldn't, why would you expose a function to the view, which isn't needed to the view? Also you get a better overview which functions is internally when only using function funcName().
You shouldn't use the $scope to declare every function you are using, especially if it's not connected to the view.
However, there are some cases you need to use the $scope in a function not connected to view, for example if you want to emit/receive/broadcast a message on the scope tree or access something on a parent scope (although it's not necessarly a good practice).

Angular - ngModel not updating when called inside ngInclude

First and foremost, the plunker: http://plnkr.co/edit/v1uTz5
This is a working demo of the issue I am running into.
I have a ng-include to include a partial.
Inside the partial I have an text input with ngModel AND directive.
The model updates accordingly inside the include, but any interaction outside the include is ignored. The {{test}} outside the include doesn't update, but the {{test}} inside does.
The directive, when called, handles the enter key and calls the correct scope and function. However, the $scope.test variable has never been updated, but $scope.testFinal is updated and the ng-include template renders it appropriately. Trying to reset the $scope.test model does not work either.
Am I missing something here? Or is this a bug with the directive or with the ng-include?
Instead of using a primitiive to define the variable, make it an object.
$scope.model={test:''};
Directives create their own scope for each item. When you equate a primitive to a new scope variable, it has no binding to the original, however when original is an object, a reference is created , not a copy, and changes made in one will reflect in the other
Simple explanatory example:
var a ='foo';
var b= a;
/* now change a*/
a='bar';
alert( b) // is still 'foo'
now do the same with object:
var obj_1= {a:'foo'};
var obj_2=obj_1;
/* now change obj_1.a*/
obj_1.a='bar';
alert( obj_2.a) // change to obj_1 will also change obj_2 and alert returns "bar"*/
Your Plunker Modified
Read this article on angular wiki for more detailed explanation
John Lindquist has a video about it. Although he doesn't quite explains why you need to use an object.
Basically every time there is a new non-isolated scope, every property of the parent scope is copied to the new scope and, as #charlietfl explained, copying a primitive type really creates a "copy" but with objects what you get is a reference, hence the changes are global.
ng-include creates its own scope and it is different than outer scope. Use this.test instead of $scope.test inside ng-include template. It will work properly.

Resources