Hooking on DOM events without a new directive per element - angularjs

I render table like so (there are many more fields):
<tr ng-repeat="client in clients">
<td>{{client.name}}</td>
<td>£{{client.total}}</td>
//...
</tr>
The model (clients) changes in the controller often (an ng-click handler changes the data in the $scope). I would like to highlight all cells that has changed.
A highly related question on SO is this, but it introduces new markup (highlighter="person.firstName") on each element, whereas I simply want AngularJS to highlight any change on the table; that is, every time the DOM changes, I wish to add a highlight class.
How can this be achieved?

Related

Will ng-repeat bind my custom directive DOM elements when they get reloaded?

I have a ng-repeat that lists users and uses a custom directive.
My custom directive has some event handlers like click handlers etc.
This vm.UserList will get modified every time a drop down list value is changed in the UI. My question is, will the event handlers get updated whenever the UserList is modified by a drop down list?
The dropdownlist on change will make a remote API request and then set the JSON result of the users to the value of the UserList.
<div ng-repeat="u in vm.UserList">
<div><div my-custom-directive user-id="{u.id}" >{u.email}</div></div>
</div>
</div>
Yes, it does. According to angularjs documentation:
ngRepeat uses $watchCollection to detect changes in the collection.
When a change happens, ngRepeat then makes the corresponding changes
to the DOM:
1- When an item is added, a new instance of the template is added to the
DOM.
2-When an item is removed, its template instance is removed from
the DOM.
3-When items are reordered, their respective templates are
reordered in the DOM.
So your directive gets added to the page including all of the event handlers.

List of objects that need different logic

I want to display a list of events of very different types that should have different UI logic. Yes, they have common properties (like name, date/time, location etc) but also sets of custom properties that can be simple text, typeahead items, drop down lists etc. Depending on the specific event type (there will be tens of them) I need to handle user input in different ways. For example, on select a typeahead item I want to clear two other fields etc.
I'm gonna display those events using ng-repeat and dynamically load template views depending on the specific event type. These views will have proper controllers that are specific to the business object. I still haven't make it work but please advice me.
Is loading type-related views with controllers inside is a good idea
for this task?
Would directives instead of controllers be better?
Is there a way to dynamically set controller/directive name in the HTML attribute?
Any other advices?
yes
yes, use directives. If you have a base event definition, it is probably best to define an element directive for that and use attribute directives to extend/customize the functionality for different event types.
not exactly, but you can use ng-switch on your list item element.
example:
<li ng-repeat="event in events" ng-switch on="event.type">
<my-event event="event" first-type ng-switch-when="type1"></my-event>
<my-event event="event" second-type ng-switch-when="type2"></my-event>
<my-event event="event" third-type ng-switch-when="type3"></my-event>
<my-event event="event" ng-switch-default></my-event>
</li>
Use require: 'myEvent' in your extending directives to gain access to the base myEvent controller.
Demo

How to preserve DOM elements when using ng-repeat with filter?

I have an ng-repeat with a filter. When some items are filtered out by the filter and then they are restored after another filter change there are new DOM elements created for these items. If there was any DOM manipulation on the item it gets lost after item is hidden and restored with filter.
Is there a way to keep the DOM elements, even when item is removed by filter?
I tried using track by, but it doesn't help.
Here is a fiddle that recreates the problem.
Steps to recreate:
Click the button to apply colors to DOM elements
Type something in the filter input (for example 'ap') to hide some of the elements
Remove the filter. The restored elements lost their style.
Angualr is dynamically adding and removing those templates. By template I mean whatever tag(s) are inside your ng-repeat. There is no way to preserve that in an ng-repeat. Instead, if you want this color change to be preserved, it needs to be a part of the model you are ng-repeat ing over. Does that make sense?
Add the color directly to the template style="color: {{fruit.color}}"
See this for what I am talking about
http://jsfiddle.net/nferjvsp/1/

ng-repeat Efficiency and Working

I am using ng-repeat for my Model render in angular ,
if i Push new Element in Model/Collection , Will angular only deal with Update or Loop through the whole model again.??
My experience (using Angular version 1.2.7) is such that whenever something changed in collection, the whole ng-repeat was repainted.
You can easily test it by modifying the generated DOM. For example by adding custom attributes like my-id="1", my-id="2" etc to the DOM elements.
Then change something in your collection, which will trigger new $digest cycle.
Angular will pick up the change and redraw the DOM -> your custom attributes will disappear.
So I would argue that Angular loops through the whole model.
In the documentation it is clearly mentioned:
ngRepeat
ngRepeat directive instantiates a template once per item from a collection. Each template instance gets its own scope
Angular associates an identity to every item, the elements already associated to the existing items of the collection won't be recreated.
Hence, only elements that are removed from the collection, are removed from the DOM. Furthermore, if an item moves within the collection it doesn’t need a new scope, but it needs to be moved in the DOM.

dynamic modify DOM with angularjs

I am new with angularjs and I am trying to add some dynamic content to the DOM.
What I want to do is a little bit like twitter for example.
I have a table with different rows and if the user click on a row, there is some details ajax loaded just ender the row.
I have a template for the row details (which I want to display (and compile) just ender the clicked row.
As I don't realy understand how to trigger a directive with click, I have tried to do it from a controller function (with ng-click on the row) but I can't compile (I only have the template displaying).
If anyone has an idea how to do it (and best, a way to do it with directive as it seems to be the right way to do it).
Thanks
Since it is not clear how complicated your template is that you want to add, you may not need a directive — ng-repeat on the <tr> element may be enough. On the AngularJS home page, the "Wire up a Backend" demo, tab list.html shows how to dynamically add rows to a table using ng-repeat, with data that was retrieved via the query() method. Is this sufficient for your needs?

Resources