Dynamic column class for Zurb-Foundation columns using AngularJS - angularjs

I'm using Foundations with AngularJS. I have a case where I'm trying to display things in columns using ng-repeat.
<div class="four columns" ng-repeat="resultsObject in resultsObject">
<div ng-bind-html-unsafe="resultsObject"></div>
</div>
This works fine. But the issue is that the columns size could be anywhere from 1-5. And I'd like the display to update dynamically. So if there are only 2 columns, it would adjust to the correctly column display.
<div class="{{$rootScope.columnCount}} columns" ng-repeat="resultsObject in resultsObject">
<div ng-bind-html-unsafe="resultsObject"></div>
</div>
When I try doing something like the above code, {{$rootScope.columnCount}} doesn't display anything. (I have verified that it does accurately store the correct column based on input.) It shows up in the source as <div class=" columns"> instead of <div class="3 columns">.
Is this an issue with using an angular variable and ng-repeat in the attribute? I've used {{$index}} within the class - so I know it can print things out within the class attribute.

Without seeing some code, I would assume the number of columns is equal to resultsObject.length so can you try:
<div class="{{resultsObject.length}} columns" ...
Here is a short demo.. Check out the class of each li and you'll see the count.
http://plnkr.co/edit/fFRTjD5gse8tnJmDig2I?p=preview
Lastly can you just try to bind to class="{{columnCount}} columns">... I don't think you need to reference the $rootScope.

The problem was an issue with variables overlapping. Apparently I had used columncount in other places in my app. So it just kept getting set back to an null. Simply changing the name solved the problem.

Related

ng-repeat view "lagging" behind the actual model?

HTML:
{{vm.regions}}
<div ng-repeat="region in vm.regions">
{{region}}
</div>
On button presses, the model a.k.a vm.regions gets updated in the controller. For example vm.regions = [].
I can see that the array {{vm.regions}} is instantly updated, but the elements in the div take at least a second to update, meaning you can see old elements for a bit in the newly updated list, for example.
What is causing this?
It is in AngularJs Best Practices to always add "track by $index" in order to inprove performances.
{{vm.regions}}
<div ng-repeat="region in vm.regions track by $index">
{{region}}
</div>
Link : https://docs.angularjs.org/api/ng/directive/ngRepeat
Try using vs-repeat. It applies virtual scrolling to ng-repeat which increases its performance drastically even if you are not using one time binding.
http://kamilkp.github.io/angular-vs-repeat/#?tab=8

Filter a directive by using a div wrapper or within the directive tag

I'm trying to go with the best approach and avoid unnecessary rendering/processing time in my AngularJS app when choosing between 2 directives to be displayed in the page inside an ngRepeat loop, want to know which is the best way:
If by setting the ng-if directly in the directive html element, like:
<div ng-repeat="element in list">
<my-directive-a ng-if="someFunction(element)"></my-directive-a>
<my-directive-b ng-if="!someFunction(element)"></my-directive-b>
</div>
Or by moving out the first <div> from the directive's template and use it as a wrapper for each directive. For instance:
<div ng-repeat="element in list">
<div ng-if="someFunction(element)">
<my-directive-a></my-directive-a>
</div>
<div ng-if="!someFunction(element)">
<my-directive-b></my-directive-b>
</div>
</div>
NOTE: The starting <div> element on each directive could be modified behave the same so I will basically take that out of the directive's html and moving it outside the directive declaration in order to place the ng-if there
What would be the best approach for this case? Are there any performance implications from doing it one way or another? Or is it just the same thing? Consider that the number of elements in the list could get really big.
They are quite the same, but you can improve performance with one-time binding, but only when element does not change at runtime (for example, let's say that it has property name, and your someFunction is like return element.name === 'John'). Angular just stop observing this function when it returns value, and watches will be deleted. There are 2 prerequisites to use this solution:
Elements properties in list does not change (if you rely on them in someFunction), for example if you rely on name property name must not change, because watcher on someFunction is note available.
When list changes or its elements properties change, you reload all list (for example, you fetch it from server again if you know that change occurred)
What you get with this? There is no watches after my-directives are drawn on ng-ifs, and when something changes, new reference is bound to list (for example, it comes from server) and everything will be redrawn, ng-ifs will run again and when will become stable (function returns value) then will be unbound. How it looks like? Like this:
<div ng-repeat="element in list">
<div ng-if="::(someFunction(element))">
<my-directive-a></my-directive-a>
</div>
<div ng-if="::(!someFunction(element))">
<my-directive-b></my-directive-b>
</div>
</div>
Two colons before expression. But be aware, that with one-time binding it's easy to mess up - you need to be sure that you test your code enough to be sure it works.

Adding another column when row reaches XX

I am trying to make a nice display of my array data within an element that has a certain width/height. What I want to do is that when my data reaches the bottom of the element to start a new column and continue with printing the data within that next column and so on/forth
Any help is much appreciated!
My code:
<div class="repeater" ng-repeat="files in files"> {{files.name}}
<div class='progress-bar'>
<div class='percentage' ng-style="style">
</div>
</div>
</div>
Current view:
HTML/CSS solution
This should be better solved by CSS than by your application logic. You could display the file names as list and adapt the approach at
How to display an unordered list in two columns?
to display them in multiple columns.

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.

Ambiguity in the use of ngRepeat

I have following problem with using of AngularJS ngRepeat.
The issue can be viewed in this jsFiddle.
http://jsfiddle.net/zono/9rmEs/2/
The user can choose character and after this get all combination
of chosen characters in alphabet. Eg:
A - A-B, A-C, A-D and etc.
B - B-A, B-C, B-D and etc.
Everithing works properly but when user change value of selected
character the combination does not get updated. I solved this problem
with adding following code.
<span style="display: none;">
{{item.combionations = getCombinations(item)}}
</span>
And "hack" it. But there must be normal solution.
I would be very grateful for any ideas and recommendations.
Best regards.
Update
In case you plan to do more complex calculations based on the selection this simplified approach would not work. In general it is also better to encapsulate state in some data structure. In your case you could design a structure like this:
{ letter: "A", combinations: ["A-B", "A-C", ... ] }
To update the combinations array you can use ng-change="updateItem(item)" and some update function. Whenever you change the selection the array combination gets updated:
$scope.updateItem = function(item) {
item.combinations = getCombinations(item.letter);
}
I put this in a new fiddle.
You can easily solve this issue by using the model you bound to ng-select in the ng-repeat.
In the select you used item.model. Angular will update its value in the scope whenever you change the selection.
<select data-ng-model="item.model" ng-init="item.model=allLetters[0]" ng-options="value for value in allLetters">
</select>
When you use the same scope variable in ng-repeat you should get the desired behavior.
<div ng-repeat="letter in allLetters">
{{item.model}}-{{letter}}
</div>
Take a look an the updated fiddle.
The problem is that you compute combionations once at the begenning (ng-init="item.combionations=getCombinations(item)"). After that it never gets updated when you change item.model.
You could solve this problem (and also make sure created[...].combionations is kept up-to-date) like this:
<div data-ng-repeat="item in created">
<div ng-repeat="combination in item.combionations = getCombinations(item)">
{{combination}}
</div>
...
See, also, this short demo.

Resources