Angular JS Nested ng-repeat for bootstrap badges - angularjs

Im trying to tag different video items in a bootstrap table. I'm already using an ng-repeat to loop over the array of objects which store video data. I'm now trying to create a nested ng-repeat to loop over another array of "tags" within the ng-repeat that creates each table row.
I'm getting some weird results though. I was hoping that I could just put an ng-repeat on the td and then put the angular expression in a span with the boostrap class "badge". Any thoughts as to whats going wrong?
http://jsfiddle.net/jheimpel/6nh100ca/
<tr ng-repeat="topic in topics">
<td><a ng-href="#/{{topic.url}}"><i class="fa fa-play"></i></a></td>
<td>{{topic.topic}}</td>
<td>{{topic.date}}</td>
<td>{{topic.presenter}}</td>
<td ng-repeat="tag in topic.tags">
<span class="badge">{{topic.tags}}</span>
</td>
</tr>

Change it to
<span class="badge" ng-bind="tag"></span>
You're telling it to print out the array you're ng-repeating instead of the object the ng-repeat is giving you. Also ng-bind is better, see this

Related

How can I use ng-bind-html as an element?

For an Angular 1.2 project, I'd like to render a subset of <td>s inside of a table row using ng-bind-html in order to reduce the number of watchers. I cannot easily render all <td>s this way because some of them have ng-clicks, ng-if's and ng-classes attached to them.
Currently the ng-bind-html element is rendered as td children elements of the <td> that it's called in. However, ng-bind-html cannot be called as an element (must be an attribute).
Any ideas on how to approach this? (I've been looking at some jquery but I'm pretty new to that area).
<tr>
<td><span>{{entry.name}}</span></td>
<td ng-bind-html="generateStaticHtmlColumns(entry.data)"></td>
<td>{{entry.address | number}}</td>
<td ng-if='!entry.loading' tooltip position="bottom">{{entry.phone | number}}</td>
</tr>
Essentially, I'd like the <td> calling using ng-bind-html to be replaced with the "td"s it's returning rather than appending them as children.

Angular vs-repeat performance issue with tables with 7k rows

I am using angular vs-repeat to render around 7k rows in a table. If I use vs-repeat for table body, the rendering was very slow.
<table class="table">
<tbody vs-repeat style="width: 100%;">
<tr ng-repeat="row in list track by $index">
<td>{{::row[listColumns[0].colName]}}</td>
<td>{{::row[listColumns[1].colName]}}</td>
<td>{{::row[listColumns[2].colName]}}</td>
<td>{{::row[listColumns[3].colName]}}</td>
<td>{{::row[listColumns[4].colName]}}</td>
</tr>
</tbody>
If I use vs-repeat without tables, in my case I used divs. Its rendering very fast
<div vs-repeat class="table-body">
<div class="row" ng-repeat="row in list track by $index">
<div class="col-md-4">{{::row[listColumns[0].colName]}}</div>
<div class="col-md-2">{{::row[listColumns[1].colName]}}</div>
<div class="col-md-2">{{::row[listColumns[2].colName]}}</div>
<div class="col-md-2">{{::row[listColumns[3].colName]}}</div>
<div class="col-md-2">{{::row[listColumns[4].colName]}}</div>
</div>
</div>
Please suggest how to improve performance for table?
With vast collections of items that render many DOM elements, even the most negligible processing of items inside an ng-repeat can choke your app.
DOM-related solutions that check if elements are in view don't tell you if nested components have been loaded and rendered completely, leading to errors.
My solution to this problem is angular's limitTo : limit: begin filter, along with iScroll or native scrollTop and scrollBottom callbacks, which raise or reduce the begin index in the controller according to the browse direction - sort of frontend pagination where only a specific number of items are shown at the DOM.
<tr ng-repeat="item in items | limitTo : 100 : 600 track by $index">
<span>{{ item.property }}</span>
</tr>
Then you can find the optimal limitTo number that work out best for the app - while keeping it light, quick, and agile as Angular should be.
use ng-repeat on small set of an array. Do pagination or lazy loading. store data to temporary array which you want to display rather having n-repeat on 7k records.
Thoughts?
Thanks!

Knockout foreach accessing 2D json array

Hope someone can help me out with this:
I'm working with knockout and have the following json array:
[[174302,"BUSINESS - APPLICATION TO CONDUCT A BUSINESS FROM HOME.pdf",".pdf","DK89639"],[120183,"Glovent-Brochure.pdf",".pdf","DK472894"]]
inside my "consumerData" variable.
As you can see there are 2 arrays with 4 elements inside each.
Here is how I am trying to access it:
<div data-bind="foreach: consumerData" style="margin-bottom:100px;">
<table>
<tr>
<td colspan="2">
<p style="font-size:larger; margin-bottom:5px;"><a data-bind="attr: { href: 'http://someaddress/address/'+consumerData[0]+''+consumerData[2]+'?key='+consumerData[3]+'' }"><div data-bind="text: consumerData[1]"></div></a></p>
</td></tr>
</table>
</div>
So this is looping twice which is correct but how do I access my data inside each array?
PLease help!
Thanks!
Regards
Francois
You can access unnamed data within a loop by accessing the $data object (instead of consumerData again), which represents the current context
See this fiddle:
https://jsfiddle.net/5c6y46bo/
Also, you don't need to put a div inside your link to hold the text of the current object, just put the text binding within the <a> element's binding alongside the attr binding.

ng-if is not working under nested ng-repeat

I am getting some server response data in two different JSON as:
userlist{id,name,type...}
and
tasklist{assign_to,tester,title,description...}
here, I need to show the task of the corresponding user.
so, I have nested the tasklist under the userlist using ng-repeat as:
<div ng-repeat="user in userList">
<table>
<tr><th>Name </th><td>{{user.name}}</td></tr>
<tr><th>Type </th><td>{{user.type}}</td></tr>
</table>
<div ng-repeat="task in taskList">
<div ng-if="task.assign_to==user.id || task.tester==user.id">
<table>
<tr><th>Title </th><td>{{task.title}}</td></tr>
<tr><th>Task Desc </th><td>{{task.description}}</td></tr>
</table>
</div>
</div>
</div>
but it's not working. As all the tasks are showing for every user.(Means ng-if is not working).
Any suggestion would be appreciated.
Angularjs code is case-sensitive. Please check variable name in scope. From the code you pasted above, the two lists should be :
userlist{id,name,type...}
and
tasklist{assign_to,tester,title,description...}
Use same in HTML. I think you are using taskList and userList (with capital L, use same name in JS and html)
All it was about the version actually. 1.0.7 doesn't support ng-if. Hence, 1.1.5 worked for me.

Conditionally adding elements in ng-repeat block

Is it possible to add stuff to the markup based on condition?
Like in this example, when I want to add td only on the first iteration (only for the first element of myData)?
<tr ng-repeat="m in myData">
<td>{{m.Name}}</td>
<td>{{m.LastName}}</td>
#if myData.indexOf(m) = 0 then // something like that
<td rowspan ="{{m.length}}">
<ul>
<li ng-repeat="d in days">
{{d.hours}}
</li>
</ul>
</td>
</tr>
Yes, AngularJS has 2 directives for this occasion:
The ng-show / ng-hide family of directives can be used to hide (by
using display CSS rules) parts of the DOM three based on a result of
evaluating an expression.
If we want to physically remove / add parts of the DOM conditionally
the family of ng-switch directives (ng-switch, ng-switch-when,
ng-switch-default) will come handy.
At the end of the day both solutions will give the same visual effect but the underlying DOM structure will be different. For simple use cases ng-show / ng-hide is probably OK, but larger portions of the DOM should be treated with ng-switch.
For the use case from this question I would advice using ng-switch.
The best solution should be:
<tr ng-repeat="m in myData">
<td>{{m.Name}}</td>
<td>{{m.LastName}}</td>
<td ng-if="$first" rowspan="{{myData.length}}">
<ul>
<li ng-repeat="d in days">
{{d.hours}}
</li>
</ul>
</td>
</tr>

Resources