DCSIMG
שמירת המצב של העמוד כשעושים Back בדפדפן לעמוד שהיו בו שינויים בתוך UpdatePanel - שלמה גולדברג (הרב דוטנט)

שלמה גולדברג (הרב דוטנט)

מרצה בסלע ויועץ בעולם ה - net.

שמירת המצב של העמוד כשעושים Back בדפדפן לעמוד שהיו בו שינויים בתוך UpdatePanel

 

הבעייה ידועה.
 
יש לכם דף שיש בו UpdatePanel עשיתם שינויים בעמוד, עברתם לדף אחר וחזרתם ע"י לחצן Back של הדפדפן כל השנויים שעשיתם נעלמו והדף חזר למצבו ההתחלתי, לעומת זאת אם לא היה UpdatePanel בדף ועברתם לדף אחר כשתחזרו ע"י Back כל השינויים ישמרו.
 
ב - IE8 יש לזה פיתרון מובנה - אבל זה עניין לפוסט אחר, כאן אני רוצה להראות טריק מעניין שיכול לעזור לפתור את הבעייה.
 
דוגמא לבעייה:
נניח שיש לי Grid על העמוד כברירת מחדל הוא עולה ריק ויש DropDown - שבזמן שהוא משתנה ה - grid מקושר למידע מתאים.
 
קוד ה - html
 

<asp:ScriptManager ID="sm" runat="server">

</asp:ScriptManager>

 

<asp:UpdatePanel ID="udp" runat="server">

    <ContentTemplate>

 

        <asp:GridView ID="gv" runat="server">

        </asp:GridView>

 

        <asp:DropDownList ID="ddl" runat="server" AutoPostBack="true"

                OnSelectedIndexChanged="ddl_SelectedIndexChanged">

            <asp:ListItem Text="Select" Value="0"></asp:ListItem>

            <asp:ListItem Text="City" Value="1"></asp:ListItem>

            <asp:ListItem Text="Street" Value="2"></asp:ListItem>

        </asp:DropDownList>

 

    </ContentTemplate>

</asp:UpdatePanel>

 

<asp:Button ID="Button1" Text="Redirect" runat="server" OnClick="Button1_Click" />

 
 
קוד שמתבצע בזמן שינוי ערך ב - DropDown
 

protected void ddl_SelectedIndexChanged(object sender, EventArgs e)

{

    if (ddl.SelectedValue == "1")

    {

        DataTable table = new DataTable();

        table.Columns.Add(ddl.Text);

 

        table.Rows.Add("בני ברק");

        table.Rows.Add("תל אביב");

        table.Rows.Add("ירושלים");

 

        gv.DataSource = table;

        gv.DataBind();

 

    }

    else if(ddl.SelectedValue == "2")

    {

        DataTable table = new DataTable();

        table.Columns.Add(ddl.Text);

 

        table.Rows.Add("הרצל");

        table.Rows.Add("רבי עקיבא");

        table.Rows.Add("ז'בוטינסקי");

 

        gv.DataSource = table;

        gv.DataBind();

    }

}

 
כשנשנה את ה - DropDown נקבל ערכים מתאימים ב - Grid.
 
הבעייה מתחילה כשאנחנו לוחצים על הלחצן Redirect - הנה הקוד שלו
 

protected void Button1_Click(object sender, EventArgs e)

{

    Response.Redirect("Default.aspx");

}

 
כשנלחץ back בדפדפן נקבל Grid ריק. במידה ולא היה לנו UpdatePanel - לחצן ה - back היה זוכר את המצב של ה - grid.
 
 
הפיתרון שהשתמשתי בו היה כזה.
 
1. הוספת HiddeField שיחזיק את הסטטוס מהיכן הגענו, האם הדף נטען מהשרת או מההיסטוריה של הדפדפן.
2. בהנחה שיש לנו את המידע, בזמן onload (בצד ה - JS) נבדוק האם הגענו מההיסטורייה של הדפדפן, במידה וכן, נלך לשרת ונדאג שימלא את הנתונים מחדש.
 
מימוש:
הוספת HiddenField

<asp:HiddenField ID="hidStatus" runat="server" />

 
בפונקציית Page_Load נכתוב ל - hidden שהגענו מצד השרת
 

protected void Page_Load(object sender, EventArgs e)

{

    hidStatus.Value = "server";

}

נוסיף קוד ללחצן Redirect שינקה את הערך של ה - hidState
 
 

<asp:Button ID="Button1" Text="Redirect" runat="server"

 OnClick="Button1_Click" OnClientClick="ResetHid()" />

 

function ResetHid() {

    var hid = document.getElementById('<%=hidStatus.ClientID %>');

    hid.value = '';

}

 
 
נוסיף לחצן (מוסתר) שנוכל ללחוץ עליו אם נגלה שהגענו מה - back

<asp:Button ID="HidButton" runat="server" OnClick="HidButton_Click"

    style="visibility:hidden" />

 
נכתוב ב - body קריאה לפונקציה
 

<body onload="CallBack()">

 

function CallBack() {

    var hid = document.getElementById('<%=hidStatus.ClientID %>');

    if (hid.value != 'server') {

        document.getElementById('<%=HidButton.ClientID %>').click();

    }

}

 
בשרת בזמן שינוי של ה - DropDown נשמור ב - Session את מה שנבחר
 
 

protected void ddl_SelectedIndexChanged(object sender, EventArgs e)

{

    Session["ddl"] = ddl.SelectedValue;

 
 
והנה הקוד של הלחצן המוסתר.
 

protected void HidButton_Click(object sender, EventArgs e)

{

    if (Session["ddl"] != null)

    {

        ddl.SelectedValue = Session["ddl"].ToString();

        ddl_SelectedIndexChanged(sender, e);

    }

}

 
(סתם התעצלתי להוציא את הקוד שמתבצע בזמן שינוי ב - DropDown לפונקציה - ולכן קראתי ישירות לאירוע).
 
 
בגדול זה יכול לפתור לנו את הבעייה.
 
אז לסיכום - מה שצריך לעשות זה את הדברים הבאים.
 
1. HiddenField שמאותחל לערך 'server כשהדף נטען מהשרת.
2. כל פעם לפני שיוצאים מהדף למחוק את הערך מאותו HiddenField.
3. ב onload של ה - body לבדוק האם הגענו מהשרת או מההיסטוריה.
4. במידה והגענו מההיסטוריה - להפעיל מתודה בשרת שתדע לאחזר את הנתונים.

תוכן התגובה

Pini Dayan כתב/ה:

שלמה נשמה,

יש פתרון הרבה יותר אלגנטי ל MS ajax פתרון מובנה שנקרא History

הנה כתבתי על זה בפוסט

blogs.microsoft.co.il/.../microsoft-ajax-from-the-bottom-up-part-9-and-last.aspx

זה מאפשר לך לשמור state של דך בעזרת שינוי ב QS ולייצג את המצב לוגית.

# September 17, 2009 10:56 AM

Shlomo כתב/ה:

אחלה, תודה

# September 17, 2009 11:40 AM

משה כתב/ה:

פיתרון נוסף שהייתי מציע - שימוש ב-UserData.

# September 21, 2009 1:03 AM
שלח תגובה

(שדה חובה)  

(שדה חובה)  

(אופציונלי)

(שדה חובה) 

Please add 6 and 8 and type the answer here:


Enter the numbers above: