Titanium JIRA Archive
Alloy (ALOY)

[ALOY-492] Events are blocked in special cases in TableViewSection

GitHub Issuen/a
TypeBug
PriorityMedium
StatusClosed
ResolutionInvalid
Resolution Date2013-01-30T17:25:57.000+0000
Affected Version/sn/a
Fix Version/s2013 Sprint 03
ComponentsRuntime
Labelsleftnavbutton, rightnavbar, tableviewsection
Reporterfarid fadaie
AssigneeTony Lukasavage
Created2013-01-16T18:48:11.000+0000
Updated2014-01-28T23:55:20.000+0000

Description

The bug can reliably be reproduced. The attached code can reproduce it. The expected behavior is to add a row to the tableviewsection. However, once we add the row and rerender the tableview (with setData), all of the eventlisteners on the tableview stop working (even the ones on other rows). There are some weird ways to workaround the bug (but none of them can be used in my case and that's why I'm reporting this): *If you only have the rightNavBAr or leftNavbar (not both). Not even sure why this is related but if you remove one of buttons, it just works! *Use InsertRowAfter (or appendRow) instead of setData to add the row to the section. This approach works but the issue is if you don't have any row in a section and want to add a row to that section, it just won't work. *move win.open() to somewhere after setData in the code. This approach also works but I cannot really do it in my case. All of the workarounds look pretty bizarre to me and I don't even know why they work.

Attachments

FileDateSize
index.js2013-01-16T18:48:11.000+0000409
index.xml2013-01-16T18:48:11.000+0000566

Comments

  1. Tony Lukasavage 2013-01-17

    Duplicate of ALOY-466
  2. Tony Lukasavage 2013-01-29

    reopening as it may not be an exact duplicate of ALOY-466
  3. Tony Lukasavage 2013-01-29

    What is the goal of this test sample? It's really confusing. It's also tough to know how it should layout with no TSS file for the style. Why are you executing this line:
       $.tableView.setData($.tableView.data)
       
    That's going to reinitialize the table with its existing data, which would explain why all of your prior changes would be gone. Also, you'd be better suited to put the onClick on the table itself, not on each row. It will be much faster and you can still access the individual row in the handler:
       function onClickHandler(e) {
           var row = e.row;
       }
       
  4. farid fadaie 2013-01-30

    Let me just explain that this is a complete sample (just create a project and add use this as index.js and index.xml. You don't really need the tss here (for reproducing the bug). It's not the best way to communicate this but bare with me. I'll try to explain. "That's going to reinitialize the table with its existing data, which would explain why all of your prior changes would be gone." There is no prior listener attached. The only listener is the one that is attached to the Row. I am not sure why using $.tableView.setData($.tableView.data) just to rerender the table (to basically show the newly added rows) should remove the listener that is attached to one of the rows. Having said that, if you remove Alloy from the equation everything works in Titanium. What you are suggesting (to attach the handler to the table and not the row) is possible but it's a pain to handle complex objects with it when you are dynamically creating the rows and attaching functions with various scopes to them. Handling all cases in one big function that is attached to the table (as oppose to the row) just makes the code unreadable and complex.
  5. Tony Lukasavage 2013-01-30

    $.tableView.setData($.tableView.data) is not going to add new items, it's just going to re-render what's already in it. Perhaps you were storing the table data in an array or something when you were developing without Alloy? I need to see what you were doing without Alloy to see how perhaps it got messed up in translation. I'm pretty sure you think $.tableView.setData($.tableView.data) is doing something that it's not, but I'll need to see the non-Alloy code to be sure. I think the table handling the click can be handled without making the code unreadable and complex, but that is your preference, that is up to you. It will be less performant than allowing the table to handle the clicks, though.
  6. farid fadaie 2013-01-30

    var x = Ti.UI.createTableViewRow({title:'test'}); x.addEventListener('click', function(){alert('yy')}); $.projects.add(x); $.tableView.setData($.tableView.data) $.projects is already a section in $.tableView (look at index.xml). Adding a row to this section adds it to the table. You just have to rerender it to see it. This part of the code actually works. When/if you run this code, you will see this new row actually gets added to $.projects section BUT for some reason x.addEventListener('click', function(){alert('yy')}) gets forgotten. Basically it's like this line is not there. Everything else works.
  7. Tony Lukasavage 2013-01-30

    This app works fine if you remove the window you are overlaying on the table. It is likely receiving those click events and causing the problem, despite its transparency. I understand that the native highlight is still firing on the table, but that is likely an iOS platform issue. You should probably consider just using Ti.UI.View to overlay in iOS apps rather than a full-blown Ti.UI.Window to prevent this going forward. In the future, please reduce your issue down to the smallest test case possible. It would have saved us a lot of time here. For reference, this code works exactly as you would expect it to:
       <Alloy>
       	<Window id="rightMenu">
       		<TableView id="tableView">
       			<TableViewSection id="projects">
       				<TableViewRow onClick="clicked" class="right_menu_item" title="Sign out" >
       				</TableViewRow>
       			</TableViewSection>
       			<TableViewSection id="section2">
       				<TableViewRow onClick="clicked" class="right_menu_item" title="Account" >
       				</TableViewRow>
       			</TableViewSection>
       		</TableView>
       	</Window>
       </Alloy>
       
       function clicked(){alert('clicked')}
       
       $.rightMenu.open();
       
       var x = Ti.UI.createTableViewRow({title:'test'});
       x.addEventListener('click', function(){alert('yy')});
       $.projects.add(x);
       $.tableView.setData($.tableView.data);
       
  8. farid fadaie 2013-01-30

    I am not sure if this is an IoS issue. If you just don't use Alloy and stick to the original titanium it just works (without any change in its architecture) We did try to get the sample to its minimum but the issue is weird and the sample code that I sent was the smallest that we could come up with. The actual code is much bigger/more complex than this. But I understand what you are saying and will try :)
  9. Tony Lukasavage 2013-01-30

    Again, you haven't shared your non-Alloy equivalent of this test case, so I can make no assessment of it. Not just the few lines in question, but the actual test case.

JSON Source