Диаграмма Google не рисуется при вызове UpdatePanel ScriptManager.RegisterClientScriptBlock

Я запускаю сценарий на стороне клиента на основе событий в ASP.NET UpdatePanel. Это работает, когда страница действительно обновляется, но не работает, когда один и тот же код запускается одним из событий UpdatePanel. Похоже, что для управления диаграммой Google требуется window.onload. Есть ли работа вокруг?

<asp:UpdatePanel ID="UpdatePanel1" runat="server">    
<ContentTemplate >
    <asp:Timer ID="Timer1" runat="server" Enabled="False" Interval="3000" ontick="Timer1_Tick">
</asp:Timer>
    <asp:Panel ID="Panel1" runat="server" Visible="True">
        <asp:Label ID="QuestionText" runat="server" Text=""></asp:Label>
        <br />
        <asp:RadioButtonList ID="ResponseList" runat="server">
        </asp:RadioButtonList>
        <br />
        <asp:Button ID="SubmitResponse" runat="server" Text="Submit" onclick="SubmitResponse_Click" />
    </asp:Panel>
    <asp:Panel ID="Panel2" runat="server" Visible="False">
        <div>
            Thank you for taking this poll...                
        </div>
    </asp:Panel>
    <asp:Panel ID="Panel3" runat="server" Visible="False">
        <div id="chart_div">
            Google Chart showing Survey Results should appear here.
        </div>
    </asp:Panel>
</ContentTemplate>

protected void Page_PreRender(object sender, EventArgs e)
    {
        GetPoll();
        string drawGoogleChartScript = GetDrawGoogleChartsScript();

        if (!UserHasResponded(SPContext.Current.Web.CurrentUser.Name))            
        {               
            QuestionText.Text = Poll.Question;
            ResponseList.DataSource = Poll.PossibleResponses;
            ResponseList.DataBind();
            Panel1.Visible = true;
            HiddenPollId.Value = Poll.PollId;
        }
        else if(_submitButtonClicked && !_thankYouMessageHasBeenDisplayed )
        { 
            //Return and wait for the Timer event to fire
            return;
        }
        else if(!_submitButtonClicked && _thankYouMessageHasBeenDisplayed )
        {
            //The Timer event has fired
            _thankYouMessageHasBeenDisplayed = false;
            ScriptManager.RegisterStartupScript(Page, Page.GetType(), "DrawChart1", GetDrawGoogleChartsScript(), false);
        }
        else
        {
            //The user has already taken the poll - visible on every visit after they take it.
            if (Panel1.Visible == true)
            {
                Panel1.Visible = false;
            }
            if (Panel3.Visible == false)
            {
                Panel3.Visible = true;
            }

            ScriptManager.RegisterStartupScript(Page, this.Page.GetType(), "DrawChart2", GetDrawGoogleChartsScript(), false);                               
        }
    }


protected void SubmitResponse_Click(object sender, EventArgs e)
    {
        _submitButtonClicked = true;
        using(SPSite site = new SPSite(SiteUrl))
        {
            using( SPWeb web = site.RootWeb ) 
            {
                SPList responseList = web.Lists[ResponseListName];                    
                SPListItem item = responseList.AddItem();

                item["Response"] = ResponseList.SelectedItem.Text;
                item["PollId"] = HiddenPollId.Value;
                item["UserId"] = SPContext.Current.Web.CurrentUser.Name;

                item.Update();
            }
        }

        //Hide the Question
        Panel1.Visible = false;

        //Show "Thank you for taking the poll message"
        Panel2.Visible = true;

        //Start the Timer - (countdown to swith over to the results)
        Timer1.Enabled = true;

    }       



    protected void Timer1_Tick(object sender, EventArgs e)
    {
        _submitButtonClicked = false;
        _thankYouMessageHasBeenDisplayed = true;

        //Hide the "Thank you for taking the poll" message
        Panel2.Visible = false;

        //Show panel with the 'char_div' where the chart will be injected
        Panel3.Visible = true;

        //Stop the timer
        Timer1.Enabled = false;

    }

GetDrawGoogleChartsScript() Returns the following in a string:

    <script type='text/javascript'>
       google.load('visualization', '1.0', {'packages':['corechart']});
       google.setOnLoadCallback(drawChart);

       function drawChart(){
         data = new google.visualization.DataTable();
         data.addColumn('string', 'Agreement');
         data.addColumn('number', 'choice');
         data.addRows([['Strongly Disagree', 3],['Disagree', 1],['Neutral', 1],['Agree', 1],['Strongly Agree', 2]])
         var options = { 'title': 'My manager has taken positive steps to increase engagement since the Q12 Survey.', 'width': 400, 'height': 300 };
         var chart = new                  google.visualization.BarChart(document.getElementById('chart_div'));
         chart.draw(data, options);
    }
</script>

Я использую ASP.NET UpdatePanel, чтобы представить вопрос опроса + кнопку отправки, затем сообщение «Спасибо за участие в опросе» и, наконец, представить результаты опроса в диаграмме Google.

Диаграмма работает, когда страница обновляется, но я не могу заставить ее работать с помощью асинхронных событий.

Я публикую много кода, но основная проблема заключается в том, что когда мы повторно входим в Page_PreRender после срабатывания события Timer_Tick, мы выполняем строку: ScriptManager.RegisterClientScriptBlock(Page, Page.GetType(), "DrawChart1", GetDrawGoogleChartsScript() , ЛОЖЬ);

(Это тот же код, который выполняется, когда мы перезагружаем страницу после завершения опроса.) Но ничего не происходит! Скрипт вообще не загружается.

Параметры гистограммы на самом деле вычисляются динамически, поэтому я должен использовать ScriptManager.RegisterClientScriptBlock, чтобы добавить его на страницу.

JavaScript даже не попадает в исходный код страницы в случае события Async, хотя я могу наблюдать за выполнением строки, вызывающей ScriptManager.RegisterClientScriptBlock.

После 4 дней, когда я бился об это головой, я очень «затрудняюсь» с этим, поэтому любая помощь, которую вы можете оказать, будет очень оценена.

Ваше здоровье,

Трей Кэрролл


person Trey Carroll    schedule 24.08.2012    source источник
comment
Как вы объявили _submitButtonClicked и _thankYouMessageHasBeenDisplayed? Статичны ли они?   -  person McGarnagle    schedule 19.09.2012


Ответы (2)


Я думаю, что ваша проблема связана с тем, что вы либо установили элементы управления видимостью в коде, либо на стороне клиента. Вы не можете сделать и то и другое и заставить его работать правильно. Вы знаете об этом? У меня было много головной боли из-за этого ограничения.

person Bill Blankenship    schedule 18.09.2012

Сценарий Google не зависит от window.onload; Я подозреваю, что происходит следующее:

  1. Событие таймера срабатывает, и блок скрипта передается клиенту
  2. Клиентский скрипт загружает библиотеку визуализации Google, запускает обратный вызов drawChart --> ничего не происходит, потому что Panel3 еще не виден
  3. Таймер срабатывает снова, и теперь Panel3 становится видимым. Клиентский скрипт запускается снова, но на этот раз google.setOnLoadCallback(drawChart) не вызывает обратный вызов, поскольку скрипт Google уже загружен.

Чтобы исправить это, я предлагаю простой тест. Проверьте, загружен ли уже Google API; если это не так, вызовите функцию drawChart вручную:

if (typeof google.visualization == 'undefined') {
    google.load('visualization', '1.0', {'packages':['corechart']});
    google.setOnLoadCallback(drawChart);
}
else {
    drawChart();
}

Это должно привести к правильному отображению диаграммы.

person McGarnagle    schedule 18.09.2012