What is the active:true construct in Angular js? - angularjs

I am following the phonecat Angular tutorial here and I was wondering what this code was doing:
<div class="phone-images">
<img ng-src="{{img}}"
class="phone"
ng-repeat="img in phone.images"
ng-class="{active:mainImageUrl==img}">
</div>
Is {active:true} an angular construct? If so, what does it do and where is the documentation? Why the single {}?
Will {{img}} work in ng-src even though it's above the ng-repeat line?

ng-class is a directive, that expects an Angular expression. The type of the expression can be a string (the name of the class), an array of strings (the names of the classes), or an object where keys are the names of the classes, and values are booleans telling if the class must be added or not.
In that case, the expression is a literal JavaScript object, just as you would write it in JavaScript code:
var object = {active: mainImageUrl == img};
And the CSS class 'active' will thus be added if mainImageUrl == img is true.

Related

when should I write code with `{{}}` and without `{{}}` in html of angular js project

May be This is a simple question but it is challenging for me.
In angularJS when i write {{}} in html code so i write code like this like
if i talk about dynamic id, we write like code this
<div ng-repeat = 'item in itmes track by $index'>
<div id = "div-{{$index}}">{{item.name}}</div>
</div>
If i use any model without {{}} i write this example
<input id = 'name' ng-model = "item.name"/>
whenever i am coding in angular js, i write code without {{}} then if it is not work then i try code with {{}} and vise versa. and randomly 1 will correct
Question is when i write code with {{}} and without {{}} in html code ?
After the OP explained what exactly was the problem.
So, the question here is very simple: when do we use {{}} and when we don't in the context of ng-model.
When you do a <input type=... ng-model="someModel>, what you're essentially telling Angular is: "Here is an input element; attach $scope's someModel variable to the value of this input element.
Now, you can use this in your JavaScript controller like so: $scope.someModel, but what about HTML? We have a templating language in Angular, and when you give it some variable (say someModel), it'll search its $scope for it, and then put in the value there. If it is unable to, it'll throw a nasty error.
In essence, {{}} GETS the value, without that, you generally set the variable to gold the value of something.
Very simply put, AngularJS thinks that the content within the brace is an expression, which must be resolved. Once it is, Angular puts the value of the resolved expression there. In the most basic of the terms, you just tell it: "Here is some expression; put the evaluated value instead."
In ES6, we call it template strings.
So, you'll use it for expressions which mutate after every iteration. Say, a loop or something. Places where you know what the answer is, or you have static content, you won't use it.
Say you have the following bit of code:
...
...
$scope.figureOne = 10;
in your controller.js and the following in its view file:
<div>My age is {{ figureOne }}</div>
Angular gets the value from the $scope, and puts it there; so, the rendered form will be: My age is 10. However, if you had the following
<div>My age is figureOne</div>
This time, Angular knows that there is nothing to evaluate or resolve, so, it'll just render it as it is: My age is figureOne.
I hope I made it clear! :)
Angular directives have different types of parameters. Some parameters (#) expect string values and some expect javascript expressions (=) (with variables bound to $scope).
There's no obvious way to know which parameter expects what type of value (aside from looking at documentation).
If a variable expects static string value and you have an angular expression
then you'll need to evaluate it by wrapping in {{}}
If there variable expects an expression and you have an expression
simply type that in.
It's the best to avoid using {{}} where possible, your dynamic ID will fail when Angular hasn't interpolated the expression yet, use ng-attr-id="div-{{$index}} for that. https://docs.angularjs.org/guide/directive#-ngattr-attribute-bindings
Another example, if you have a slow connection and Angular isn't loaded yet users will see the {{}}, you can avoid this by using ng-bind="".
See this thread for more info: AngularJS : Why ng-bind is better than {{}} in angular?
It is very simple.
{{something}} - used for one way binding(Static).
<input type="text" value="{{something}}">
Now if you change its value in HTML ,you can not get it by $scope.something in js.
but If you use ng-model="something",you can get its value in JS.
This happens because ng-model is two way binding.
<input type="text" ng-model="something">
Mostly We use ng-model for forms and {{}} to display static information like User details or else.

Angular Expression Interpolation

I came through the following example of ng-class="expression" in a book.
http://plnkr.co/edit/fJGT5L9HZXvgAiAyXwlW?p=preview
ng-class="{error:isError,warning:isWarning}"
I get the controller logic, but my doubt is in the interpolation happening here.
What does the following scenarios mean (what is the evaluated value) and Why?
ng-class="{error:true,warning:true}"
ng-class="{error:true,warning:false}"
ng-class="{error:false,warning:true}"
ng-class="{error:false,warning:false}"
From the ngClass arguments docs:
The result of the arguments evaluation can be a string
representing space delimited class names, an array, or a map of class
names to boolean values. In the case of a map, the names of the
properties whose values are truthy will be added as css classes to the
element.
So in your case the result of the arguments after evaluation is a map which produces:
ng-class="{error:true,warning:true}"
=> class="error warning"
ng-class="{error:true,warning:false}"
=> class="error"
ng-class="{error:false,warning:true}"
=> class="warning"
ng-class="{error:false,warning:false}"
=> no class attribute
ng-class="{error:true,warning:true}" => class="error warning"
ng-class="{error:true,warning:false}" => class="error"
ng-class="{error:false,warning:true}" => class="warning"
ng-class="{error:false,warning:false}" => no classes set
As you could notice ng-class get just hash where keys are names of classes and values -- conditions (if true than class will be added to class attribute)
So, ng-class just uses angular expression and check what data it returns (string, array or hash-map) then it applies certain parser to get final classes array to put it to class. One of this is described above.
Angular expressions
Angular like as Javascript uses eval mechanism to execute code (expression), but unlike JS Angular uses safe eval called $eval([expression], [locals]) (Docs)
I'm strongly recommending you to read this article about Angular expressions to understand how it works.
Angular will add (or append to the existing class attr) the following class attribute to the element:
class="error warning"
class="error"
class="warning"
No class attribute added

AngularJS get DOM element after push

i'm using ng-repeat to display some array values (messages). How do i get the corresponding DOM element after pushing it to the messages array?
I want to add and remove a class(es) from the added dom element.
Thank you,
Bernhard
The Angular way is not to directly manipulate the DOM but to use the directives provided to you by the framework. To change the CSS classes applied to an element, use ngClass, ngClassEven, and ngClassOdd.
<div ng-repeat="item in items">
<span ng-class="{active: isActive(item)}">{{item}}</span>
</div>
The parameter to ngClass is a JavaScript object which keys are the names of the CSS classes, and values are expressions. For each key-value pair, if the expression results in true, the class is added, otherwise it is removed.
ngClassEven and ngClassOdd can be used to apply classes only to even or odd elements of the repetition.

Angular's ng-class: combine enumerated (array) classes and condition-based ones?

I have an array with classes set in the controller (has to be this way, it's read from page's meta-template). I'd also like to have a conditional classes applied to the same element. Is it possible?
Edit, more info: my html element has classes that originate from two sources - one is a set of classes created by the controller (they are provided by a service outside of my code, I can't have them hardcoded in the view). The other source is an output of a condition (for example: if "$scope.activeElement === name_of_this_element, add 'active' class).
In ng-class directive, I can't use an object notation for unspecified list of classes (the first source) and I have to use an object notation for conditional classes.
Edit: found a solution (see below).
Another option is to write an ng-class in this way
<div ng-class="[item.class, item.errorClass, item.locked ? 'locked-item' : '']"></div>
I found a solution - I placed the "fixed" classes in a regular class attribute (converted that string to an array first) and conditional ones in ng-class object, like this:
<td ng-repeat="cell in row.cells" class="{{cell.cssClass}}" ng-class="{active: condition}">
The fact that you stored a array of classes' name is not relevant here.
HTML
<div ng-class="arrOfClasses[condition]"></div>
Angular
app.controller('myCtrl', function($scope) {
$scope.arrOfClasses = ['class1', 'class2', 'class3'];
$scope.condition = 1; // what ever number here
});
A good way, and also to avoid using {{}} inside class would be with just an expression:
<td ng-repeat="cell in row.cells" ng-class="(condition ? 'active ' : '') + cell.cssClass">

dynamically change a html element's class by angualrjs

I'm trying to change some html elements' class attribute by AngularJs' $scope value. But it seems I can't.
<div class="{{object.someAtrribute}} > Content </div>
So, how can i do this actually?
Thanks.
You want to use the ng-class directive. It takes an object with a set of class names and boolean expressions:
<div ng-class="{'class-name': boolean}"></div>
So, in your example, you can do something like this:
<div ng-class="{'larger-than-content': item.foo > content}"></div>
Since this is an object, you can add several classes:
<div ng-class="{'one': foo == 1, 'two': foo == 2, 'three': foo == 3}"></div>
Note: The quotes on the class names are not necessary, although I often have dashes in my class-names. In that case, the quotes are necessary (you are describing a JS object), so I tend to use them always for consistency.

Resources