ng-switch-when does not have break statement? - angularjs

I am using ng-switch and expecting that it will be a break statement after each condition. I tested with following with condtion gradeA and it display both Grade A-1 and Grade A-2. Am i missing some configuration? If not how to make ng-switch to contain break statement?
<div ng-switch="type">
<div ng-switch-when="gradeA">
Grade A-1
</div>
<div ng-switch-when="gradeA">
Grade A-2
</div>
</div>

That's because ng-switch-when works like ng-if, which means if the condition satisfies, the block would be "shown" (technically it's created instead).
According to the documentation:
ngSwitchWhen: the case statement to match against. If match then this case will be displayed. If the same match appears multiple times, all the elements will be displayed.
In your example, both cases are "case: gradeA", and thus both are shown.
If you wish to conditionally 'break out', use a nested ng-if or another nested ng-switch.

Working Plnkr
In both div, you have used ng-switch-when="gradeA". So code inside each ng-switch-when with matching value GradeA will be executed. That is why both Grade A-1 and Grade A-2 are displayed.
Your code should look like:
<div ng-switch="type">
<div ng-switch-when="gradeA-1">
Grade A-1
</div>
<div ng-switch-when="gradeA-2">
Grade A-2
</div>
</div>
Notice that in above code, first ng-switch-when with matching value gradeA-1 and second ng-switch-when with matching value gradeA-2. So there is no chance to be displayed both data.
Hope that solve your problem.
Update: Performance Issue from this answer
One solution I used was to use ng-show/ng-hide. These directives do
not modify the DOM structure, but instead use CSS to hide/show the
elements. It can be faster, but beware that the DOM could become very
large if you fall into the trap of trying to contain all of
templates/DOM elements of your web site in memory at the same time in
this manner.
OP of that question also answered with a solution.

Related

How do I display an Angular directive conditionally?

I'm attempting to use Angular directives to create custom input field types. For example, I have a type called "duration" which draws three separate hours, minutes, and seconds fields. I'm trying to use the directive as an attribute of an input element, and the directive replaces the input element.
For example, in the following code:
<input duration>
Would be rendered as a <div> with several inputs inside of it, and the original input would be out of the picture.
I'm running an ngRepeat loop through several form fields of different types, including duration. I'd like to find a way that only requires me to put one input in the HTML, with the duration attribute applied only if the field is supposed to be of duration type. I tried the following:
<div ng-repeat="field in fields">
<input type='{{field}}' ng-attr-duration="field==='duration'">
</div>
The problem with that code is that every element is rendered as duration because ng-attr-duration gets evaluated to duration='false' when the field is not duration, which triggers my directive.
Is there a way for me to apply the directive conditionally without having to define multiple <input>s to reduce redundancy in my code?
Take a look at what the directive docs say about ng-attr:
When using ngAttr, the allOrNothing flag of $interpolate is used, so if any expression in the interpolated string results in undefined, the attribute is removed and not added to the element.
Note that you need to be using curly braces so Angular will interpolate the expression. And, if your expression has an undefined term in it, the attribute won't be added.
How about something like this:
<div ng-repeat="field in fields">
<input type='{{field}}' ng-attr-duration="{{field==='duration' ? true : undefined}}">
</div>
The true in the ternary expression can be whatever you want, just not undefined.
What i can think of you can use condition if-else of ng-switch
<div ng-repeat="field in fields">
<div ng-switch on="field">
<input ng-switch-when="true" type='{{field}}' ng-attr-duration="field==='duration'">
<input ng-switch-default="true" type='{{field}}'>
</div>
</div>
It will also maintain readability of code.

AngularJS $index inside ng-switch

I am trying to access $index of ng-repeat and place it inside ng-switch-when. Here is the last thing I have tried. Small piece of what I am trying to do:
<li ng-repeat="contact in contacts" ng-switch on="MenuSelected">
<span ng-switch-when="$index">{{ contact }} {{$index}}</span>
</li>
MenuSelected I have define in my controller with 0 for example, and I have 2 contacts for test. I have tried to mix ng things in different tags and everything fall (just show lines), so I don't think that is the problem. When I remove $index and place for example 0 everything show up.
you cannot use expressions with ngSwitch
refrer this doc
Be aware that the attribute values to match against cannot be expressions. They are interpreted as literal string values to match against. For example, ng-switch-when="someVal" will match against the string "someVal" not against the value of the expression $scope.someVal
this implies that ng-switch-when="$index" $index is treated as a string not as a index value
use ngIf instead
<span ng-if="$index == MenuSelected">{{ contact }} {{$index}}</span>
here is the working Fiddle

Conditional print in Angularjs and Bootstrap LESS

I have a conditional print requirement in Angular and Bootstrap environment. The requirement is to print a div when the condition exists.
On the HTML code:
<div class="print" ng-show="objects[0].exists">
///My print Part
</div>
On the LESS code:
>.print{
.visible-print-block;
}
What's happening in my case is .visible-print-block is overriding the Angular condition and printing the div irrespectively of the condition.
You want to use the ng-class directive
So your coude would look like:
<div ng-class= '{"print": objects[0].exists}'>
///My print Part
</div>
Using this solution the class 'print' will only be applied if the result of objects[0].exists is true.

ng-repeat not working inside angular-deckgrid

I am Using angular-deckgrid to create pinterest like view
Here is the Code I have written
<div deckgrid source="items" class="deckgrid">
<span data-ng-repeat='i in card'>{{ i }}</span>
</div>
I am expecting the value of i in the ng-repeat, but that seems to be not going in the loop.
Can any one please suggest me the solution
The data-ng-repeat is redundant. Be default, deckgrid will loop over your items variable and assumes it is an array.
Make sure items is an array and remove the data-ng-repeat.

Why does using ng-repeat to iterate html fail when the html contains divs?

When I use ng-repeat to iterate the following code, everything is fine:
<p ng-repeat="user in users">
<input size="50" ng-model="user.name"></input>
<span>Foo</span>
</p>
However, using the following fails:
<p ng-repeat="user in users">
<input size="50" ng-model="user.name"></input>
<div>Foo</div>
</p>
In the latter case, it looks like the div is excluded from the loop and appended only once after the input tags that have been repeated as expected.
I'm trying to understand the difference in behaviour towards div tags.
Thanks for any insights.
EDIT: The question was already answered, but here's a js-fiddle that allowed me to demonstrate the issue: http://jsfiddle.net/f26Cg/5/
You cannot nest <div> elements in <p> element: as shown here, it's permitted to contain so-called phrasing content only.
As <div> opening tag is considered to be an end of <p> element, technically its corresponding element is outside of <p> in the second case - that's why it's not repeated.
I'll quote Josh's answer to this question : Directive inside ng-repeat only appears once
It is actually related to how your browser will handle blocks inside a non-allowing blocks tag.
I imagine this is the browser's doing. Technically, paragraph tags are
only allowed to contain inline elements, which div is not. Some
browsers (most?) will automatically close the <p> when hits an
unauthorized tag. If you inspect the DOM, you will see that even the
div that makes it into the DOM from the ngRepeat is not inside the
generated paragraph.
Josh

Resources