How do I create a read-only ng-repeat? - angularjs

Initial rendering is very slow in ng-repeat. How do I create a read-only version of ng-repeat, such that when the array that you're iterating over changes, the rendered HTML does not change

A double colon makes things in Angular read-only. Use the following syntax:
<ul>
<li ng-repeat="item in ::items">{{item.name}}</li>
</ul>

if read only, have you tried bindonce?
https://github.com/Pasvaz/bindonce

Related

Is there any directive that acts like a "with" in angular?

Say you have an object yourObject on the scope and you want to access some deep properties like the following :
<ol>
<li ng-bind="yourObject.thing.map.one"></li>
<li ng-bind="yourObject.thing.map.two"></li>
<li ng-bind="yourObject.thing.map.three"></li>
</ol>
Is there any built-in directive that could make it look more like this:
<ol ng-with="yourObject.thing.map">
<li ng-bind="one"></li>
<li ng-bind="two"></li>
<li ng-bind="three"></li>
</ol>
UPDATE
A similar question was already. Please see Equivalent of {{#with}} in angular
One way I would do this scenario is by implementing a controller that will have a variables to those an array of one, two three... and then using ng-repeat to loop over that.
So for ng-controller, you could write, ng-controller="SomeCtrl as ctrl"
and then ctrl.arrayVariable would hold an array of all the data you want to show
To make matters very simple, you could use ng-repeat to loop through the data.
So, possibly, ng-repeat="var in ctrl.arrayVariable"
Anyways, I'm not sure exactly how your code is structured, but it should work in most instances.
Long story short, ng-repeat is awesome

Is there a way to stop angularjs from watching a variable for changes?

I have a variable I need to put in a template, but it's only created and never updated or removed. It is, however, referenced in multiple areas of the template. It's used in ng-repeat, so it's an object. Not sure if that matters.
But I want to reference the variable once and stop angularjs from watching it. Is this possible?
Are you familiar with bind once?
Angular internally creates a $watch for each ng-* directive in order to keep the data up to date, so in this example just for displaying few info it creates 6 + 1 (ngRepeatWatch) watchers per person, even if the person is supposed to remain the same once shown. Iterate this amount for each person and you can have an idea about how easy is to reach 2000 watchers. Now if you need it because those data could change while you show the page or are bound to some models, it's ok. But most of the time they are static data that don't change once rendered. This is where bindonce can really help you.
https://github.com/Pasvaz/bindonce
<ul>
<li bindonce ng-repeat="person in Persons">
<a bo-href="'#/people/' + person.id"><img bo-src="person.imageUrl"></a>
<a bo-href="'#/people/' + person.id" bo-text="person.name"></a>
<p bo-class="{'cycled':person.generated}" bo-html="person.description"></p>
</li>
</ul>

How can I bind ng-repeat to the previously clicked ng-click?

I'm having a bit of trouble trying to use an ng-repeat that only references the previously clicked ng-click function.
What I'm trying to create is a demo app with dynamic dummy content.
The concept is:
Click a link from a content set and display the json data (headlines) just pertaining to that link.
I've noted the problematic repeater in the html
demo: plnkr.co
I'm kinda new to angular so if there is an easier method to doing this, any guidance would be greatly appreciated. Thank you!!
Your second block contains two nested ng-repeats: one that iterates over the contentSets, and one that iterate over the headlines of the current content. You want a single ng-repeat, which iterates over the content that has been clicked in the top block. And this clicked content is stored in the scope variable useContent by your setContent() function (called by the ng-click). So that's what you must iterate over:
<ul class="list-unstyled" >
<li ng-repeat="headline in useContent.headlines">
{{headline.headline}}
</li>
</ul>
You got it right for the <h1>, which displayed the appropriate title, BTW.
Demo: http://plnkr.co/edit/guAapCDRzPI1i51OfRAS?p=preview
Demo Plunker Here
You only need to put ng-show on the ul element, and only show it when content == useContent
<ul class="list-unstyled" ng-repeat="content in contentSets" ng-show="content == useContent">
<li ng-repeat="headline in content.headlines">
{{headline.headline}}</li>
</ul>

Angular.js - Understanding what statements can go in an ng-class query

The Angular docs are really sparse on what is acceptable in an "expression" within a conditional ng-class.
For example, I'm running an ng-repeat over a list:
<ul class="clothes">
<li ng-repeat="piece in clothes | filter:query">
{{piece.name}}
</li>
</ul>
On every third <li> element I'd like to add a class of "third". Can this be done using ng-class with something like ng-class="{third : li:nth-child(3)}" or similar?
Side-note, is there a general reference somewhere that defines and gives examples of what can be used in an Angular expression? There's some really basic stuff that I can do with vanilla Javascript/css but I can't work out how to cram it into Angular!
Just create an expression that evaluates to true or false, a bit similar to Javascript expressions but with some differences, you can read about it here.
<ul>
<li ng-repeat="item in items" ng-class="{third: !(($index+1)%3) && !$first }">{{item}}</li>
</ul>
Here is a jsBin.
In my code I am telling ng-class to add the class 'third' when ($index+1)%3 is zero and it is not the $first list item ($index, $first and $last are created by ng-repeat).
if you want to use css instead of angular for the styling, you can use the css nth selector
http://www.w3schools.com/cssref/sel_nth-child.asp
li:nth-child(3n+3)
{
background:#ff0000;
}

AngularJS - Transclude and access ng-repeat filtered list in a sub-directive,

I would like to tile elements that get in to ng-repeat (set up their css based on the filtered list)
Ideally I would like to use html markup like this:
<ul>
<li ng-repeat="row in rows">
<h6>{{row.name}}</h6>
<ul>
<li ng-repeat="item in items|filter:row" tile>{{ item.name }}</li>
</ul>
</li>
</ul>
Is it possible for me to access the list that is being passed to ng-repeat? (any other way than AngularJS - how to get an ngRepeat filtered result reference)
Can I somehow transclude the items, so the tile directive would actually apply css (I want to abstract ng-style="{top:getTop(item),left:getLeft(item)}" etc.)
Is it possible for me to access the list that is being passed to ng-repeat? (any other way than AngularJS - how to get an ngRepeat filtered result reference)
I think you'll need to do what you saw in the link you referenced:
ng-repeat="item in (filteredItems = (items|filter:row))" tile>
Assuming your tile directive does not create a new scope, it will share the scope that ng-repeat creates (one scope per item). So the filteredItems property will be available to your directive.
Can I somehow transclude the items, so the tile directive would actually apply CSS (I want to abstract ng-style="{top:getTop(item),left:getLeft(item)}" etc.)
Your tile directive has access to the li element on which it is defined. So you can simply call, e.g., element.addClass(...).

Resources