开发者

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜