Sep 10, 2012, 2:26 PM
[CLOSED] Setting ListView.SelectedIndex on server side fails
Consider following example page which initializes SelectedIndex of a ListView:
The root of the call chain is Ext.ux.data.PagingStore.execute which contains following code fragment:
- Ext.DataView.onDataChanged
- Ext.DataView.refresh
- Ext.DataView.clearSelections
Which then leaves the selection empty if it runs after the selection has been initialized.
So the root cause seems to be some indeterminisim when the deferred store load happens. Any idea how to work around this problem?
[edit] note that the initialization of the selection also seems to happen in a deferred call, namely Ext.DataView{override}.doSelection is done from a Ext.util.DelayedTask - so my problem here is that there's a race-condition about which one runs first, and for my page I'm working on I happen to lose that race most of the time, which is why it's a problem for me.
<%@ Page language="C#" autoeventwireup="true" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Test Page</title>
</head>
<body>
<form runat="server" id="wForm">
<asp:ScriptManager runat="server" id="wScriptManager" />
<ext:ResourceManager runat="server" id="wResourceManager" sourceformatting="true" scriptmode="Debug" />
<div runat="server" id="wRoot">
<ext:Window runat="server" id="wDialog" width="150" height="400" layout="Fit">
<Items>
<ext:Panel runat="server" layout="Fit">
<Items>
<ext:ListView runat="server" hideheaders="true" singleselect="true" selectedindex="0">
<Store>
<ext:Store runat="server" id="wStore">
<Reader>
<ext:ArrayReader>
<Fields>
<ext:RecordField name="Name" type="String" />
</Fields>
</ext:ArrayReader>
</Reader>
</ext:Store>
</Store>
<Columns>
<ext:ListViewColumn dataindex="Name" />
</Columns>
<Listeners>
<SelectionChange fn="function(){if(this.getSelectionCount()!=1){debugger;}}" />
</Listeners>
</ext:ListView>
</Items>
</ext:Panel>
</Items>
</ext:Window>
</div>
</form>
</body>
</html>
<script runat="server" visible="false">
protected void Page_Load()
{
wStore.DataSource = new object[] { new object[] { "A" }, new object[] { "B" }, new object[] { "C" } };
wStore.DataBind();
}
</script>
This randomly fails to initialize SelectedIndex, causing the list view selection to start empty. For debugging I added a listener to SelectionChange and it will trigger in the failure case. (Note that it depends a lot on timing so it may or may not reproduce reliably for you, but see below for my analysis of the problem.)The root of the call chain is Ext.ux.data.PagingStore.execute which contains following code fragment:
if (action === "read" && this.isPaging(params)) {
(function () {
...
this.fireEvent("datachanged", this);
...
}).defer(1, this);
From there the call chain is- Ext.DataView.onDataChanged
- Ext.DataView.refresh
- Ext.DataView.clearSelections
Which then leaves the selection empty if it runs after the selection has been initialized.
So the root cause seems to be some indeterminisim when the deferred store load happens. Any idea how to work around this problem?
[edit] note that the initialization of the selection also seems to happen in a deferred call, namely Ext.DataView{override}.doSelection is done from a Ext.util.DelayedTask - so my problem here is that there's a race-condition about which one runs first, and for my page I'm working on I happen to lose that race most of the time, which is why it's a problem for me.
Last edited by geoffrey.mcgill; Sep 28, 2012 at 9:40 PM.
Reason: [CLOSED]