An interesting case about missing onclick events on DOM updates

37 views
Skip to first unread message

Alexandre Verri

unread,
Feb 12, 2014, 11:21:44 AM2/12/14
to ang...@googlegroups.com
Hello, I would like to share an interesting case about missing onclick events on DOM updates.

In order to best describe the problem, please check the following Fiddle example:



Sander Elias

unread,
Feb 12, 2014, 11:44:12 AM2/12/14
to ang...@googlegroups.com
Hi Alexandre,

You are reassigning your array every second. Angular has no way knowing that you put the same stuff again, so it re renders the whole thing.
This is exactly where the track by option came from/for.


Regards
Sander

Alexandre Verri

unread,
Feb 12, 2014, 12:08:41 PM2/12/14
to ang...@googlegroups.com
Hello Sander,

I was wondering if any elegant solution like this existed. Thank you very much for the information. It worked as expected. 

Regards,
Alexandre

Alexandre Verri

unread,
Feb 12, 2014, 12:19:14 PM2/12/14
to ang...@googlegroups.com
The only problem with 'track by' is when there are new information in array. In this case, the new information will not be displayed.

Is it possible to handle the new data?

Sander Elias

unread,
Feb 12, 2014, 1:51:37 PM2/12/14
to ang...@googlegroups.com
Hi Alexandre,

Hmm, never had problems in this area. However, if you change the an array so that the same ID has new info, you need to change the id. otherwise Angular does not know it has to update the row.
Makes any sense?
If you put up a plunk with your actual problem, I will take a look at it, and give you a workaround.

Regards
Sander

Alexandre Verri

unread,
Feb 12, 2014, 2:14:14 PM2/12/14
to ang...@googlegroups.com
Hi Sander,

I don't know why it fails in my application. In my GUI the only way to know about an object being added or removed is observing the list. The data comes from the server via JSON. But I made a Fiddle with the scenario, and it is working fine there, please check it:


You may select the first name in the list, "George Washington", and click on the buttons. The selected name will not change, and AngularJS will re-render the DOM accordingly. This is exaclty what I want. 

Regards,
Alexandre

Alexandre Verri

unread,
Feb 12, 2014, 2:37:57 PM2/12/14
to ang...@googlegroups.com
I created an example in JSFiddle, covering all the use cases from my GUI. They are working fine:


I am glad that you have shared the information about the 'track by' feature.

Regards,
Alexandre


Em quarta-feira, 12 de fevereiro de 2014 16h51min37s UTC-2, Sander Elias escreveu:

Sander Elias

unread,
Feb 13, 2014, 1:48:36 AM2/13/14
to ang...@googlegroups.com

Hi Alexandre,

I’m glad you figured it out. Your example shows nicely that the track by feature works as a charm!
There is still something that has to be added, the track by feature requires an unique identifier.
As an example, it you don’t have an unique ID, you can combine it with the name like this:
<tr ng-repeat="a in actualArray track by a.id+a.name">. As an alternative you can also do
<tr ng-repeat="a in actualArray track by $index"> but then it’s not binded to your data at all.

Regards
Sander

Alexandre Verri

unread,
Feb 13, 2014, 6:29:14 PM2/13/14
to ang...@googlegroups.com
Hi Sander, 

thank you very much for your help. I added a unique ID to each object. I have another interesting case:

The table gets very big, with thousands of lines. I'll add a pagination in order to avoid excessive scrolling. I need to have all data in the page, I can't use live scroll. I won't send all the table information every second. I will send only the information that was changed in the last 5 seconds. This will reduce the network traffic. In this case, if I use the same approach as we discussed in this topic, the AngularJS will delete the old data from table when receiving only a small part of whole data.

I would like to extend or doing another patch in order to indicate to AngularJS that I don't want to delete any information in this case. The usage of 'track by' feature in ng-repeat is mandatory! I don't want to live without 'track by' any more.

Do you have any ideas?

Sander Elias

unread,
Feb 13, 2014, 10:21:27 PM2/13/14
to ang...@googlegroups.com
Hi Alexandre,

Before I give an answer to that I have a couple of questions.
  1. How large are we talking about? 1500 rows, or 15000 rows?
  2. How large is each row? 
  3. Is this an desktop-only app? 
  4. You are sending every second, the changes of the last 5 seconds? eh?
  5. How much changes are arriving? <1% 10%
  6. Are those just new rows? 
  7. if 6 is no, can you split out the additions from the modifiers on the server?
I probably forgot to ask a few things, but those are the important ones.

Regards
Sander

Alexandre Verri

unread,
Feb 13, 2014, 10:38:24 PM2/13/14
to ang...@googlegroups.com
Hi Sander, 

please check my answers.


Em sexta-feira, 14 de fevereiro de 2014 01h21min27s UTC-2, Sander Elias escreveu:
Hi Alexandre,

Before I give an answer to that I have a couple of questions.
  1. How large are we talking about? 1500 rows, or 15000 rows?
It could reach 30000 rows.
  1. How large is each row? 
Each row has 14 columns, with no more than 20 characters each.
 
  1. Is this an desktop-only app? 
Yes. 
  1. You are sending every second, the changes of the last 5 seconds? eh?
Yes. 
  1. How much changes are arriving? <1% 10%
Average: 1%, but could reach 10% sometimes. 
  1. Are those just new rows? 
No. It contains new rows and updates in old rows. 
  1. if 6 is no, can you split out the additions from the modifiers on the server?
Yes, I can split out them.

Sander Elias

unread,
Feb 13, 2014, 11:04:57 PM2/13/14
to ang...@googlegroups.com
Hi Alexandre,

Ok, we are talking about a data-set that's up to 8Mb, with up to 800Kb mutations every second. That's a lot of data!
First thing that strikes me, is that you are sending every second. If you are sending the last 5 seconds every second, your'e basically sending 4 seconds of duplicates every second.
Those duplicates need to processed too, every second again. Loose this overhead! Best thing you can do for performance is drop down to a 4 or 5 second interval for getting your
data.
The data is in the form of an array I suppose, is every row an array or an object?
Move this data to a service, you can handle the updates in the service too.
You don't want to traverse 30.000 rows if you have 300 to 3000 new/changed rows. Let me do the math for you,
on 30.000 rows with 1% changes you would have 9.000.000 iterations.
You need to create an index to your data, so you can update it easily, with just 1 iteration of the new data!
if you have splitted out your additions and your changes, this is easier to do.

Angular will hand you some tools to help with this, but a large part of your problem isn't angular specific.  Just some good old programming skills, and knowledge of database handling is needed!

Regards
Sander





Alexandre Verri

unread,
Feb 13, 2014, 11:39:20 PM2/13/14
to ang...@googlegroups.com

Thank you  very much for the tips.  I'll move to a service. I made a mistake in the calculus. The update is about 30 rows per second,  in average. The max update will be 300 per second,  but rarely occurs. The idea for the index is great. Every row is an object.

--
You received this message because you are subscribed to a topic in the Google Groups "AngularJS" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/angular/dI61qYt_VCk/unsubscribe.
To unsubscribe from this group and all its topics, send an email to angular+u...@googlegroups.com.
To post to this group, send email to ang...@googlegroups.com.
Visit this group at http://groups.google.com/group/angular.
For more options, visit https://groups.google.com/groups/opt_out.
Reply all
Reply to author
Forward
0 new messages