Загрузка пользовательских контроллеров по запросу на вкладках jquery

У меня есть несколько вкладок jquery для usercontrol, которые загружают отдельный пользовательский элемент управления под каждым. Каждый пользовательский элемент управления уникален. Сейчас все работает нормально, но общий ответ страницы слишком медленный. Чтобы повысить производительность, я пытаюсь загрузить несколько пользовательских элементов под этими вкладками по требованию (то есть по щелчку вкладки). Возможно, без обратной почты... ajaxish. Может ли кто-нибудь вести меня? Я попытался выполнить этот учебник и этот тоже, но сделал не имеют успеха. Я прикрепил код для родительского usercontrol.

<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>

Ответ 1

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

<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");
   }    
...

Каждый метод будет отображать только запрошенный элемент управления. Также в вашем методе вы можете сохранять или извлекать viewstate в зависимости от ваших потребностей. После рендеринга веб-метод должен передать обратно строку html, которая будет введена в заполнители.

Если вы пробовали это и были успешны, чтобы сделать один элемент управления одновременно, но все же наблюдая медлительность, тогда у вас есть проблемы с обратным концом при получении данных. Если ваши элементы управления являются тяжелыми данными, я бы рекомендовал выполнить кеширование на стороне сервера.

Надеюсь, что это поможет.

Ответ 2

Поддерживает ли ваш пользователь контроль над пост-назад и состояние просмотра, если они работают? Относительно легко получить управляющий HTML-код пользователя, который будет отображаться на вкладке с помощью AJAX, но затем после обратной связи этот элемент управления отправит все данные на фактическую страницу (у которых может не быть загружен пользовательский контроль). Таким образом, основной контур будет

  • Отслеживание активной вкладки с помощью скрытой переменной или состояния представления.
  • Загрузите пользовательский элемент управления на основе активной вкладки в начале цикла страницы. Лучшим вариантом будет этап инициализации (не то, что состояние представления не будет доступно здесь, поэтому вам нужно сохранить активную вкладку в скрытой переменной и получить доступ к ней через коллекцию Request.Forms).
  • Дайте каждому пользователю управлять идентификатором, и он должен отличаться от вкладки к вкладке. ID очень важен для загрузки состояния представления.
  • Если вы получаете поврежденные ошибки состояния представления при переключении табуляции, вам нужно сначала загрузить пользовательский элемент управления для предыдущей вкладки, а затем на более поздней стадии страницы (скажем, load/prerender), выгрузить его и загрузить новый пользовательский элемент управления для активной вкладки.
  • Вы можете использовать заполнитель или панель управления в каждой панели вкладок для загрузки пользовательского элемента управления в нужном месте.
  • Излишне говорить, что при изменении вкладки jquery вам необходимо отправить свою форму, используя post-back script. После каждого последующего возврата вам нужно иметь script для повторной инициализации вкладок и выбора активной вкладки.
  • Для лучшего удобства пользователей добавьте всю вещь в UpdatePanel.

Ответ 3

возможно использовать привязку, указывающую на службу, определенную ниже. Например,

<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;
    }
}

Ответ 4

Вам нужно будет сделать вызов Ajax, чтобы сделать это. теперь у вас есть опции для вызова AJAX:

1 - вызов через веб-службу SOAP (ссылка ASP AjaxScriptManager будет необходима для каждого веб-метода).

2 Вызовите через службу WCF как предыдущий ответ.

3 - вызов через службу Rest.

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........
}

Ответ 6

Вы должны пойти на вторую ссылку, используя jquery и webmethod. Таким образом, вы действительно будете заполнять вкладки по требованию, не делая страницу тяжелой.

Ответ 7

На мой взгляд, самым быстрым решением вашей проблемы (но не обязательно лучшим долгосрочным) является перенос всех ваших 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.");
        }
    });
}

Некоторые примечания:

  • done и fail заменит success и error в jQuery 1.8, поэтому любой jQuery AJAX, который вы используете, должен планировать этот переход.
  • Я обернул это функцией в основном потому, что предпочитаю помещать вызовы AJAX внутри классов и функций JS, а затем ссылаться на эти объекты. С помощью меню вряд ли у вас будет несколько разных страниц, загружающих одни и те же данные через AJAX (так как это будет на какой-то главной странице, я предполагаю), но всегда полезно привыкнуть делать это вещи.
  • В зависимости от ваших чувств относительно тесно связанного 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.
    }
    
  • Некоторые люди (включая меня) используют префикс $ для различения переменных JavaScript и jQuery. Итак, здесь $placeholder является переменной jQuery.

  • Возможно, вы сможете переписать этот вызов $.ajax как type: "GET", что было бы немного более эффективным, но я не уверен, что UserControl вызовет проблемы в этом отношении. Обычно, если я загружаю всю страницу .aspx через AJAX, я использую GET вместо POST. Вам не нужно много менять, чтобы попробовать: просто отключите свойство type и измените result.d на result.

Ответ 8

Я думаю, что лучшим решением является реализация обратного вызова клиента

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

Когда пользователь нажимает на какую-либо вкладку, событие onclick вызывает js func с именем вкладки в качестве параметра, чем эта вкладка вызывает код сервера с тем же параметром.

Чем в коде вы загружаете элементы управления, которые вы хотите, в зависимости от того, какая вкладка нажата. Теперь вам нужно визуализировать элементы управления в html и отправить обратно обратно в js-функцию. Теперь у вас есть элементы управления в функции js, найдите, где вы хотите вставить код, вставьте его.

который должен работать теоретически и не сложно:))

Ответ 9

может быть полезен для вас этот вопрос (не мой) на этот вопрос:

Асинхронная загрузка пользовательских элементов управления на странице

он утверждает, что есть проблемы с этим, когда требуется, чтобы форма на пользовательском элементе была отправлена ​​обратно, но это должно быть нормально, чтобы иметь независимые формы с сообщением ajax. вам придется подумать о том, что происходит при публикации формы на странице, но не должно быть непреодолимым. не должно быть никакой причины, по которой вы не могли бы просто сделать это обработчиком ashx, о котором вы упоминали.