Best way to trigger OnClientCommand from server-side?
I've worked myself into a bit of a problem -- I'm not sure there's a graceful way out without restructuring my code. I have a server-side timer which is running and it needs to simulate clicking a tab of a RadTabStrip.
Client-Side I have the following method:
function OnClientTabSelected(sender, eventArgs)
{
FixSplitter($find(rightPaneID));
}
FixSplitter is dependent on an additional control, though:
function FixSplitter(sender, eventArgs)
{
var multiPage = $find(multiPageID);
...
}
now, server-side, I have the following:
public void DoTimerCycleTick(object sender, TimerEventArgs eventArgs)
{
GlobalSettings globalSettings = StateManager.GetStates<GlobalSettings>();
if( globalSettings.CycleEnabled )
{
if (!Equals(DateTime.Now.CompareTo(globalSettings.TimeLastCycled.AddMinutes(globalSettings.CycleInterval)), -1)) //CompareTo returns -1 when time is earlier than.
{
int nextIndex = SelectedIndex + 1;
if( nextIndex == Tabs.Count)
{
nextIndex = 0;
}
SelectedIndex = nextIndex;
LayoutManager.Instance.MultiPage.SelectedIndex = nextIndex;
LayoutManager.Instance.MultiPageUpdatePanel.Update();
//ScriptManager.RegisterClientScriptBlock(Page, Page.GetType(), "KEY", "OnClientTabSelected();", true);
globalSettings.TimeLastCycled = DateTime.Now;
}
}
StateManager.SaveGlobalSettings(globalSettings);
}
The relevant bit of this code is where I'm setting indices. Clearly, this does not trigger the OnClientTabSelected
method. Yet, I need to run the FixSplitter method.
So, I thought a quick fix for this surprise would be to register a client script. Indeed, this would probably be sufficient if not for the dependence on the multiPage. Because my MultiPage is wrapped in an UpdatePanel which is currently updating -- it cannot be fo开发者_StackOverflowund using $find(multiPageID).
$find(multiPageID) returns null where as $find(rightPaneID)
returns the expected object -- both declarations are identical and the code works smoothly in all other scenarios. I am confident in saying that the culprit is the UpdatePanel.
Do I have options other than creating a new method which does the same things as OnClientTabSelected except forces the MultiPageUpdatePanel to postback after executing -- instead of calling Update on the UpdatePanel server-side?
I recognize that there are deeper issues with this, but it's unfinished code that can't be broken apart for a few more weeks.
EDIT: After some work, here's my proposed solution. Open to critique, I'm no expert in this. :)
/// <summary>
/// Performs one tick of a timer on the chart.
/// Ticks based on time for testability and to prevent
/// weird cases when skipping the clock time forward.
/// </summary>
public void DoTimerCycleTick(object sender, TimerEventArgs eventArgs)
{
GlobalSettings globalSettings = StateManager.GetStates<GlobalSettings>();
if( globalSettings.CycleEnabled )
{
if (!Equals(DateTime.Now.CompareTo(globalSettings.TimeLastCycled.AddMinutes(globalSettings.CycleInterval)), -1)) //CompareTo returns -1 when time is earlier than.
{
int oldIndex = SelectedIndex;
int newIndex = (oldIndex + 1) != Tabs.Count ? (oldIndex + 1) : 0;
SelectedIndex = newIndex;
LayoutManager.Instance.MultiPage.SelectedIndex = newIndex;
//LayoutManager.Instance.MultiPageUpdatePanel.Update();
ScriptManager.RegisterStartupScript(Page, Page.GetType(), "KEY", string.Format("OnServerTabSelected({0});", newIndex), true);
globalSettings.TimeLastCycled = DateTime.Now;
}
}
StateManager.SaveGlobalSettings(globalSettings);
}
var showLoadingPanel = true;
function OnServerTabSelected(newIndex) {
var oldID = $find(multiPageID).get_selectedPageView().get_id();
var newID = $find(multiPageID).get_pageViews().getPageView(newIndex).get_id();
if ($telerik.$("#" + oldID).is(":visible")) {
$telerik.$("#" + oldID).fadeOut(1000, function () {
$telerik.$("#" + newID).fadeIn(1000, function () {
showLoadingPanel = true;
$find(multiPageID).set_selectedIndex(newIndex);
});
});
showLoadingPanel = false;
FixSplitter($find(rightPaneID));
return;
}
}
Can't you just overload the FixSplitter method, one that takes those two paramters, does the find and then calls the other method with all 3 parameters? That way you can always override the multiPage value when you might need it;
function FixSplitter(sender, eventArgs)
{
var multiPage = $find(multiPageID);
FixSplitter(sender, multiPage, eventArgs);
}
function FixSplitter(sender, multiPage, eventArgs)
{
...
}
If you can't overload for some reason you could use an alternative notation like DoFixSplitter.
精彩评论