Add attributes to elements in ng-repeat - angularjs

I have a
<div ng-repeat="post in getServerPosts()" >
where i ng-bind post.title and post.excerpt. Posts also have unique a post.id but it is not shown (which is what I want since I don't bind it).
I am trying to find a way to allow the user to mark a post by somehow utilizing the post.id. That way, if a user marks a post it will automatically be marked next time the ng-repeat runs (every time the page loads).
I have played around with scopes in the controller but I can't figure out how to handle the post.id this way.
Question is probably beyond newbie level and maybe there are smarter ways to do this. Any hint or advice?

Related

angular typeahead/autocomplete for contenteditable

Basically, what my client asked me to do is similar to tag friends in Facebook/youtube comment.
must start with #
a popup suggesting a list, upon selected, the value is appended back to the original contenteditable
I have tried
https://angular-ui.github.io/bootstrap/
and ngTagsInput , they are close but not enough... thanks
I bet this is what you are looking for http://angular-ui.github.io/ui-mention/example/ . I have to admit it took me quite a few days to find it (via google)
Good luck
You're building autocomplete for tags. If you plan to reuse it, then you'll need to write a custom directive. If not, then you can do a messy implementation inside of your controller.
You'll need the html element you are editing to look like this:
<div ng-model="newtag" ng-change="tagchanged()" ng-bind="newtag"></div>
ng-change will fire on change, so your function will need to have a debounce (wait a period of time) in order to wait until the user finishes typing. You can accomplish this with a setTimeout of 500ms. If it changes during that time period, kill the timeout. But if it doesnt, do your api call to get the list of potential tags and show them in a list below the field. You'll want the css for the results to let them align to the search field and hover above the rest of your page.

Why is my angular grid so slow?

So, I have made some custom directive which draws kind of a data-grid, based on floated divs (because nested flex implementation in FF sucks - but it's not the point).
How it works :
I pass some data collection to the directive via something like <the-grid data-list="parentController.displayedRows">
Inside this first directive, I have columns via something like <a-grid-column data-value="row.value"></a-grid-column> with many attributes I won't precise here.
The data-value value can be a direct expression, bound to the row on which the the-grid directive controller is ng-repeating in order to display each columns, or a function which have to be $eval-uated in order to display the intended value from the parentController.
In my <the-grid> directive controller, I have the rendering template of my grid which make a nested ng-repeat div (first one on the rows of the data-collection, second one on the columns, created in the directive), it looks like :
<div data-ng-repeat="row in list">
<div data-ng-repeat="cell in theGridColumns"
data-ng-bind-html="renderCell(row, cell)">
</div>
</div>
I have some keyboard nav in order to quickly select a row or navigate within pagination or many tabs, which does nothing more than applying some class on the selected row, in addition to update some "selectedRowIndex".
I'm using angular-vs-repeat in order to have the minimum of row divs in my DOM (because the app is running on slow computers). This works well.
The problem is that every time I'm hitting some "up" or "down" key on my keyboard, Angular is "redrawing" EVERY cells of the list.
So, let's suppose I've 200 rows in my data list, and 7 columns for each rows. First load of the page, it passes ~3000 times in the renderCell() function. Ok , let's accept that (don't really understand why, but ok).
I hit the down key in order to go to the second line of my list. It passes ~1100 times in the renderCell() function.
So yes, the result is very slow (imagine if I let the down arrow key pressed in order to quick navigate within my rows)... I can't accept that. If someone could explain that to me... Any help would be greatly accepted :)
If I make the same thing without a directive (direct DOM manipulation, with columns made by hand and not in a ng-repeat within a ng-repeat), every thing is smooth and clean.
Yes, I've look into every angular grid on the market. No one is satisfying me for my purpose, that's why I've decided to create my own one.
And no, I really can't give you some JSFiddle or anything for the moment. The whole app is really tentacular, isolating this is some kind of complicated).
Try to use bind once (angular 1.3+)
<div data-ng-repeat="row in ::list">
<div data-ng-repeat="cell in ::theGridColumns"
data-ng-bind-html="::(renderCell(row, cell))">
</div>
</div>

ng-click not working inside ng-switch

I'm beginner with AngularJs, and i have a lot of questions :/
Here's one of them :
I have links that i use to filter data. So when i click on link one, the value for the filter myFilter is one, etc.
Just to show you that my filters work, i putted two times the links (see here http://plnkr.co/edit/2G6mahkmyIixMJ1mEVKp?p=preview)
In the above links, i use ng-swich, cause i want, when i click on a link, to remove the link and only keep the text
In the bottom links, there are no ng-swich, so myFilter works perfectly
Is it possible, to make the ng-click inside the ng-swich work ?
The way you are approaching the issue involves far too much code duplication.
Also it is a bad practice to replace objects directly in the html. If you use a function bound to the scope it is cleaner and you won't run into child scope issues as much
Rather than creating four <ul> you could simply use ng-if within each <li> and use only one <ul>. This would also be a good case to create a very simple directive
HTML
<li>
<span ng-if="myFilter.trimestre==1">Avril - juin</span>
<a ng-if="myFilter.trimestre!=1" ng-click="updateFilter('trimestre',1)" href="#">Avril - juin</a>
</li>
JS
$scope.myFilter={};
$scope.updateFilter = function(key, val){
$scope.myFilter[key]=val;
}
DEMO

How do I prepend a new item to an ng-repeat list?

I have situations where I need to prepend an item to a list that is initially generated using ng-repeat. How do I do this?
<div ng-click="prependItem()>Click Here</div>
<div ng-repeat="item in items">
<div class="someClass">Item name: {{item.name}}</div>
<div class="anotherClass">Item type: {{item.type}}</div>
</div>
If I click on prependItem() I want want the new item to be added to the top of the list. Obviously, I don't want to regenerate the entire ng-repeat. I've been unable to find any documentation that would explain how to do this. Thank ahead of time for any help!
scope.prependItem = function (newItem) {
items.unshift(newItem);
};
AngularJS is smart enough to know the addition, and only create html element for it
http://plnkr.co/edit/qzIfzSP6buiQ49rDreNk?p=preview
You can see from console that only the newly added item will log messages
ng-repeat will rebuild the list if you add an item to the front of your array. If you add it to the end it's smarter in that it will only update the DOM to reflect the change for the one item you've added in.
Because you've added an item to the front, it has to move everything in the DOM so I think it just rebuilds it as it's easier to do than moving (don't quote me on that though lol). It isn't necessarily a bad thing to rebuild that list (unless it's huge, you won't even notice the refresh, if it is very big, I'd recommend showing a spinner whilst it rebuilds the html, that's the approach we've taken at work; since the user has clicked the button they're expecting the interaction so the spinner seemed like the best compromise whilst angular rerendered).

Why is my Angular JS ng-show empty list div shows up for a split second while API is being called?

<div ng-show="!activities.length">No items in feed</div>
I use the above code to show a message when a user has no items in their feed. On that same page I have a radio button to show different types of feeds (e.g. just yours, or all your friends, etc.). When the user selects a different option, it makes a post back to my API which takes a second, but while the api is grabbing the data the empty list message displays for a second.
Is there an easy way to resolve this?
Use the ngCloack directive for this:
http://docs.angularjs.org/api/ng.directive:ngCloak
The other option is to use ng-bind as many people recommend it over ng-cloak:
http://docs.angularjs.org/api/ng.directive:ngBind
I personally have had issues where even using ng-cloak there is a slight markup flash.

Resources