2011-11-17 59 views
10

我有一個用戶控件上加載一個單獨的用戶控件下每個jquery選項卡。每個用戶控件都是唯一的。它現在一切正常,但整體頁面響應速度太慢。爲了提高性能,我試圖在需求下加載這些選項卡下的少量用戶控件(即單擊選項卡)。可能沒有回帖... ajaxish。 任何人都可以引導我嗎? 我試圖按照this教程和this一個,但沒有任何成功。我附加了父用戶控件的代碼。在jquery標籤下按需加載usercontrols

<ul id="tabs"> 
<li class="active">Rewards</li> 
<li id="liCoupons">Coupons</li> 
<li id="liLibrary">Library</li> 
<li id="liProducts">Favorite</li> 
<li id="liPreferences">Preferences</li></ul><ul id="tabPanes" class="rewardsTabs"> 
<li> 
    <div class="wrapper active"> 
     <uc:Rewards ID="wellness" runat="server" /> 

    </div> 
</li> 
<li id="liCoupons"> 
    <div class="wrapper"> 
     <uc:Coupon runat="server" /> 
    </div> 
</li><li id="liLibrary"> 
    <div class="wrapper"> 
     <uc:Library runat="server" /> 
    </div> 
</li><li id="liProducts"> 
    <div class="wrapper"> 
     <uc:Products runat="server" /> 
    </div> 
</li> 
<li> 
    <div class="wrapper"> 
     <div class="preferences"> 
      <uc:Preferences runat="server"/> 
     </div> 

    </div> 
</li> 

+0

基本上我正在尋找加載一個usercontrol點擊一個選項卡時按需。沒有回傳或在更新面板中,以便用戶看不到整個頁面加載。最好用加載旋轉器。 – xoail

+0

你在'UserControl'中有什麼?您是否檢查權限級別或某種用戶組以生成不同的菜單項? – jwiscarson

+0

菜單項對於所有用戶都是相同的。他們沒有任何檢查權限或任何東西。他們是相同的所有用戶,除了它的數據(例如:帳戶信息0 – xoail

回答

12

您提到的second link應該工作。您不需要在標記中定義任何用戶控件。

<ul id="tabs"> 
    <li class="active">Rewards</li> 
    <li id="liCoupons">Coupons</li> 
    <li id="liLibrary">Library</li> 
    <li id="liProducts">Favorite</li> 
    <li id="liPreferences">Preferences</li> 
</ul> 
<div id="results" class="wrapper"></div> 

單擊每個標籤都會做一個Ajax調用

$.ajax({ 
     type: "POST", 
     url: "Default.aspx/WebMetodToCall", 
     data: data, // I wouldn't prefer passing webmethod name here 
     contentType: "application/json; charset=utf-8", 
     dataType: "json", 
     success: function (msg) { 
      $('#result').html(msg.d); 
     }, 
     failure: function (msg) 
      //error 
     } 
    }); 

到網絡的方法。

[WebMethod] 
    public static string Rewards() 
    { 
     return RenderControl("~/controls/rewardsControl.ascx"); 
    } 

[WebMethod] 
    public static string Coupons() 
    { 
     return RenderControl("~/controls/couponsControl.ascx"); 
    }  
... 

每個方法將只呈現請求的控件。同樣在您的方法中,您可以根據需要保留或提取視圖狀態。渲染之後,webmethod應該傳回要注入佔位符的html字符串。

如果您嘗試過這種方式,並且一次成功渲染一個控件但仍然看到緩慢,那麼在獲取數據時您會遇到一些後端問題。如果你的控件數據量很大,我會建議做一些服務器端緩存。

希望這會有所幫助。

+0

這很好...我們如何做標籤點擊?喜歡這個?

  • xoail

    +0

    我認爲這是一個有點臭(綁定一個AJAX方法到幾個WebMethods),但總體而言是這裏發佈的最佳解決方案(特別是考慮到問題中的特殊環境)。 – jwiscarson

    +0

    @xoail你可以將使用jquery的click事件綁定到你想要的任何DOM元素。看看http://api.jquery.com/click/ – zero7

    6

    請問您的用戶控件靠後背部和視圖狀態的有工作?使用AJAX獲取用戶控件HTML將顯示在選項卡中相對容易,但是在該控件上回發後會將整個數據發送到實際頁面(可能沒有加載用戶控件)。因此,基本輪廓將爲

    1. 使用隱藏變量或視圖狀態跟蹤活動選項卡。
    2. 在早期頁面循環中基於活動選項卡加載用戶控件。最好的選擇是初始階段(不是視圖狀態在這裏不可用,所以你必須將活動標籤存儲在隱藏變量中並通過Request.Forms集合來訪問它)。
    3. 爲每個用戶控件提供一個ID,它應該不同於製表符。 ID對於加載視圖狀態非常重要。
    4. 如果在製表切換時出現視圖狀態錯誤,那麼您需要首先加載用戶控件,然後在之後的頁面階段(比如加載/預渲染)加載用戶控件,卸載它並加載用於活動選項卡的新用戶控件。
    5. 您可以使用每個選項卡窗格中的佔位符或面板控件將用戶控件加載到正確的位置。
    6. 不用說,關於jquery選項卡的更改,您需要使用後退腳本提交表單。在每次回傳之後,您需要有一個腳本來重新初始化選項卡並選擇活動選項卡。
    7. 爲了更好的用戶體驗,將整個事物放入UpdatePanel。
    +0

    我不認爲我需要查看他們的工作狀態。你有任何示例代碼或指向我的某個地方? – xoail

    5

    也許使用指向下面定義的服務的錨點。例如,

    <li><a href="...webservices/ControlServce.svc/Content?cType=Rewards" class="wrapper active"></a></li> 
    
    /// <summary> 
    /// Service used by ajax for loading social media content 
    /// </summary> 
    [ServiceContract(Namespace = "")] 
    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)] 
    public class ControlService 
    { 
        /// <summary> 
        /// Streams html content 
        /// </summary> 
        /// <param name="type">type of control</param> 
        /// <returns>html stream of content</returns> 
        [OperationContract] 
        [WebGet(UriTemplate = "Content?cType={cType}")] 
        public Stream GetContent(string cType) 
        { 
         var tw = new StringWriter(); 
         var writer = new Html32TextWriter(tw); 
    
         var page = new Page(); 
         var control = page.LoadControl(cType); 
    
         control.RenderControl(writer); 
    
         writer.Close(); 
    
         var stream = new MemoryStream(Encoding.UTF8.GetBytes(tw.ToString())); 
    
         WebOperationContext.Current.OutgoingResponse.ContentType = "text/html"; 
         WebOperationContext.Current.OutgoingResponse.Headers.Add("Cache-Control", "no-cache"); 
         return stream; 
        } 
    } 
    
    +0

    你能展示一些示例代碼嗎? JS和代碼通過ashx處理程序吐出html? – xoail

    3

    你應該去使用jQuery和webmethod的第二個鏈接。這樣,您將實際上按需填充標籤,而不會讓頁面變得沉重。

    5

    您需要進行Ajax調用才能完成此操作。 現在您可以選擇調用AJAX:

    1 - 通過SOAP Web服務調用(每個Web方法都需要ASP AjaxScriptManager引用)。

    2-通過WCF服務作爲上一個答案進行調用。

    3 - 通過休息服務呼叫。

    4-通過Jquery ajax方法調用,但請求必須轉到外部頁面,如「Actions.aspx」,所以當你調用你的方法時,一個HTTPRequest將被製作成Actions頁面,然後它將在其響應中返回數據。 $.Ajax(url,data,action,successMethod); // this is the fastest way I tried them all.

    這裏是你應該做的事: 1上的變化選項卡時使用適當的Ajax調用方法從上面的選項調用你的方法。

    2-從成功方法中使用返回的數據,但最好使用eval(data)作爲DataTime對象。

    這裏是一些舉例說明如何使這個電話:

    var helper = { 
    callAjax: function(sentData, successFun) { 
         jQuery.ajax({ 
          url: "/Actions.aspx", 
          type: "Get", 
          data: sentData, 
          cache: true, 
          dataType: "json", 
          success: successFun 
         }); 
        } 
    }; 
    
    helper.callAjax('request=getCities&countryID=' + countryID, function (args) { 
        var result = eval(args); // this object will contain the returned data 
    var htmlData = ''; 
        for (var i=0;i<result.length;i++){ 
        // write your HTML code by jQuery like this 
        htmlData += '<div>' + result[i].title + '</div>'; 
    } 
    $('#tab3').html(htmlData); 
    }); 
    

    現在在Actions.ASPX代碼使用以下命令:

    protected void Page_Load(object sender, EventArgs e) 
        { 
         object _return = new 
         { 
          error = "", 
          status = true 
         }; 
         JavaScriptSerializer _serializer = new JavaScriptSerializer(); 
         if (!Page.IsPostBack) 
         { 
          string str = Request.QueryString["request"].ToString(); 
          switch (str.ToLower()) 
          { 
    case "getcities": 
            int countryID = Convert.ToInt32(Request.QueryString["countryID"].ToString()); 
            _return = JQueryJson.Core.City.getAllCitiesByCountry(countryID).Select(_city => new 
            { 
             id = _city.ID, 
             title = _city.Name 
            }); 
            _serializer = new JavaScriptSerializer(); 
            Response.ClearContent(); 
            Response.ClearHeaders(); 
            Response.ContentType = "text/json"; 
            Response.Write(_serializer.Serialize(_return)); 
            break; 
    } 
    // etc........ 
    } 
    
    +0

    謝謝......不幸的是,在你的回答中,我看到你正在返回json而不是usercontrol它自己。使用$ .ajax,我可以使用.ashx處理程序並返回usercontrol標記嗎? – xoail

    3

    在我看來,最快的解決您的問題(但不一定是最好的長期)是將所有的UserControl都包裝在.aspx頁面中。在這種情況下,您只需將父標記UserControl移動到新的.aspx頁面,然後通過AJAX調用它。

    假設你叫這個頁面類似Menu.aspx,並進一步假設你並不需要傳遞到這個網頁的任何數據(即,它可以跟蹤所有它自己的數據的內部),您的jQuery AJAX調用看起來是這樣的:

    function GetMenu ($placeholder) { 
        $.ajax({ type: "POST", contentType: "application/json; charset=utf-8", dataType: "json", 
         url: "Menu.aspx", 
         done: function (result) { 
          $placeholder.html(result.d); 
         }, 
         fail: function() { 
          $placeholder.html("Error loading menu."); 
         } 
        }); 
    } 
    

    一些注意事項:

    1. donefail將取代success和jQuery的1.8 error,所以任何jQuer您使用的AJAX應計劃進行此轉換。
    2. 我把它包裝在一個函數中很大程度上是因爲我更喜歡將AJAX調用放在JS類和函數中,然後引用這些對象。有了一個菜單,你不可能有幾個不同的頁面通過AJAX加載相同的數據(因爲這將在某種母版頁上,我猜),但總是習慣於這樣做的東西。
    3. 根據您對緊耦合HTML/JavaScript的感受,可以使用回調函數替換上面的$placeholder。調用,從你的頁面,你的菜單所在看起來是這樣的:

      $(document).ready(function() { 
          GetMenu(MenuCallback); 
      }); 
      
      function MenuCallback(menuHtml) { 
          $("#menu").html(menuHtml); // I'm assuming the ID of your ul/span/div tag here. 
      } 
      
    4. 有些人(包括我自己)使用$前綴的JavaScript和jQuery來區分變量。所以在這裏,$placeholder是一個jQuery變量。

    5. 您可能可以將此$.ajax呼叫重新編寫爲type: "GET",這樣會更有效一些,但我不確定UserControl是否會在這方面造成問題。通常,如果我通過AJAX加載整個.aspx頁面,我使用GET而不是POST。你不需要做太多改變就可以嘗試:只需將type屬性和result.d更改爲result即可。
    +0

    @downvoter,我的回答有什麼問題? – jwiscarson

    3

    我認爲最好的解決方案是實現客戶端回調

    http://msdn.microsoft.com/en-us/library/ms178210.aspx

    當用戶點擊一些選項卡上,onclick事件調用JS與標籤作爲參數的名稱func,比標籤調用服務器具有相同參數的代碼。

    比在代碼中加載控件要取決於哪個選項卡單擊。 現在,您需要將控件呈現爲html並將tham發送回js函數。 現在你在js函數中有了控件,找到你要插入代碼的地方插入它。

    應在理論工作,它是不復雜的:))

    0

    的asnwer(不是我)這個問題可能對你有用:

    Asynchronous loading of user controls in a page

    它指出,有這是需要用戶控件上的表單回傳的問題,但是應該可以使用ajax post創建獨立的表單。你必須考慮在頁面上發佈表單時會發生什麼,但不應該是無法克服的。不應該有任何理由,你不能讓它成爲你提到的ashx處理程序。