Inteligentní autorefresh jako user control v ASP.NET

15. dubna 2004

V některých aplikacích bývá potřeba uživateli automaticky obnovovat stránku s údaji. Zvláště se to hodí pro webové formuláře, kde by prostým obnovením stránky došlo k pokusu o opětovné odeslání údajů, což snižuje komfort uživatele. V této aplikaci navíc zapojíme již dříve publikovaný skript, který stránku obnoví jen v případě, že s ní uživatel právě nepracuje.

Obnovovat stránku a zajistit tak, aby byly údaje na stránce uživatele relativně čerstvé, se hodí zejména pro různá diskusní fora, rezervační systémy, aplikace s častou změnou obsažených údajů nebo obecně pro aplikace, u kterých není žádoucí, aby klient reagoval na neaktuální údaje. Řešením může být doplnění klientského skriptu, o kterém jsme již dříve psali v článku JavaScript jako popoháněč galejních otroků. Vytvoříme uživatelský ovládací prvek, který pak můžeme snadno použít pouhým vložením v libovolné aplikaci. V našem příkladu si navíc ukážeme, jak automatické obnovení stránky potlačit, což se může hodit pro případy, kdy například uživatel ve formuláři má vyplnit nějaké údaje a obnovením stránky bychom jej o již zadané údaje připravili.

Prohlédněte si ukázku (zdrojový kód), ve které můžete zatržítkem obnovování zapínat a vypínat. Při kliknutí na první odstavec dojde ke změně barvy textu, takže je možné vidět, zda došlo k obnovení stránky – doba obnovení je nastavena na 10 sekund od poslední aktivity ve stránce (pohyb myši, kliknutí myší, stisk klávesy, rolování okna). Všimněte si, že pokud se pokusíte obnovit stránku ručně v prohlížeči, objeví se nepohodlný dotaz, zda se mají údaje odeslat znovu.

Nejprve kód ukázkové stránky:

<%@ Page Language=“C#“ EnableSessionState=“False“ Trace=“False“ Debug=“false“ %>
<%@ Register TagPrefix=“Uc“ TagName=“AutoRefresh“ Src=“AutoRefresh.ascx“ %>
<script language=“C#“ runat=“server“>
private void Button_Click(object sender, System.EventArgs e)
{
  plcRefresh.Visible = chkRefresh.Checked;
}
</script><?xml version=“1.0″ encoding=“utf-8″ ?>
<!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“ xml:lang=“cs-CZ“ lang=“cs-CZ“ dir=“ltr“>
  <head>
    <meta http-equiv=“Content-type“ content=“text/html; charset=utf-8″ />
    <title>AutoRefresh user control</title>
  </head>
  <body>
    <form RunAt=“Server“>
      <div onclick=“this.style.color=’red‘;“>Po kliknutí zde bude text červený až do obnovení stránky.</div>
      <asp:CheckBox Id=“chkRefresh“ OnCheckedChanged=“Button_Click“ AutoPostBack=“True“ Text=“AutoRefresh“ Checked=“True“ RunAt=“server“ />
      <asp:PlaceHolder Id=“plcRefresh“ RunAt=“Server“>
        <p>Stránka se nyní automaticky obnovuje při nečinnosti po 10 sekundách</p>
        <Uc:AutoRefresh RefreshTime=“10″ RunAt=“Server“ />
      </asp:PlaceHolder>
    </form>
  </body>
</html>

Jak vidíme z kódu a ukázky, jde o triviální webový formulář, který umožňuje pomocí zatrhávacího políčka CheckBox nastavovat viditelnost PlaceHolderu. V něm může být umístěn kromě našeho autorefresh prvku také jiný obsah, který má být zobrazen tehdy, pokud se má stránka obnovovat. Naopak jej celý můžeme skrýt (a případně zviditelnit jiné prvky stránky) v případě, kdy by byl autorefresh nevhodný. Ještě doplním, že uživatelský prvek musí být zaregistrován direktivou Register.

Kód uživatelského prvku v souboru AutoRefresh.ascx:

<%@ Control Language=“C#“ %>
<%@ OutputCache Shared=“True“ Duration=“7200″ VaryByParam=“none“ VaryByControl=“ltrRefreshTime,ltrRefreshUrl“ %>
<script language=“C#“ runat=“server“>
public Int32 RefreshTime
{
  set { ltrRefreshTime.Text = value.ToString(); }
  get { return Int32.Parse(ltrRefreshTime.Text); }
}
void Page_Load(object sender, System.EventArgs e)
{
  ltrRefreshUrl.Text = Request.Url.ToString();
}
</script>
<script type=“text/javascript“>
<!– <![CDATA[
var RedirTimer = <asp:Literal Id=“ltrRefreshTime“ Text=“60″ RunAt=“Server“ />;
var MyTimer = RedirTimer;
function ResetTimer(evnt)
{
  MyTimer = RedirTimer;
}
function DecrementTimer()
{
  if(!(–MyTimer)>0)
    location.href = ‚<asp:Literal Id=“ltrRefreshUrl“ RunAt=“Server“ />‘;
}
document.onmousemove = ResetTimer;
document.onmousedown = ResetTimer;
document.onkeydown = ResetTimer;
setInterval(„DecrementTimer()“,1000);
//]]> –>
</script>

Uživatelský prvek obsahuje část klientského skriptu převzatou z již dříve publikovaného článku. V obsluze události Page_Load nastavíme URL stránky, která má být naším skriptem občerstvována – zjistíme ji jako vlastnost Url z takzvaného intrinsic objektu Request – a její hodnotu nastavíme jako Text prvku Literal, umístěného do části klientského skriptu. Prvek také nabízí veřejnou vlastnost RefreshTime typu Int32, kterou je možno určovat čas v sekundách, po němž dojde k obnovení stránky při nečinnosti. Ve skutečnosti je zadávaná hodnota po převedení na String předávána opět prvku Literal, který zajistí vykreslení odpovídající hodnoty do části klientského skriptu. Metoda get této vlastnosti vrací hodnotu vlastnosti Text převedenou na Int32 metodou Int32.Parse(). Výchozí hodnota obnovování je nastavena na 60, pokud tedy ve stránce hodnotu RefreshTime neurčíme, bude stránka obnovována každých šedesát sekund.

Prvek je doplněn o cachování direktivou OutPutCache. Důležité je vyjmenovat také prvky, na kterých má být cachování závislé (pomocí VaryByControl, viz článek o RSS v ASP.NET). Kdo nepočítá s intenzivním nasazením tohoto prvku, může cachování vynechat – výhodou zde naopak bude možnost snadno programově ovládat prvek ze stránky, což je jinak u cachovaných prvků problematické. Jakmile je totiž prvek nacachován, ztratíme k němu přístup (odkaz na něj je null) a jeho vlastnosti je možné nastavit prakticky pouze při prvním načtení stránky.

Starší komentáře ke článku

Pokud máte zájem o starší komentáře k tomuto článku, naleznete je zde.

Štítky: Články

Mohlo by vás také zajímat

Nejnovější

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna. Vyžadované informace jsou označeny *