[C#/AJAX] performance slecht bij gebruik Repeater

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • PdeBie
  • Registratie: Juni 2004
  • Laatst online: 09:31
Heren programmeurs,

Ik loop momenteel tegen een performance issue aan waarvan ik de oorzaak gevonden heb, maar even geen oplossing zie.

situatie:
site toont overzicht van 100+ artikelen. Deze worden getoond middels een repeater.
per artikel wordt er een naam, prijs en knop toegevoegd.

Nadat de gebruiker op de knop klikt wordt er een popup getoond (ajaxcontroltoolkit ModalPopupExtender (MPE)) waar een textbox in staat en een knop om het item te bestellen. Deze textbox is nodig, want wordt gebruikt om een opmerking in te vullen.

Laat ik de MPE weg uit de repeater, staat de pagina binnen no-time op het scherm. Met de MPE in de repeater duurt het een eeuwigheid. Dit komt wellicht omdat hij dan ook 100+ MPE's moet genereren, koppelen etc.

stukje code (zonder MPE):
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<asp:Repeater ID="rptArticles" runat="server" Visible="false" EnableViewState="true" OnItemDataBound="rptArticles_ItemDataBound">
    <HeaderTemplate>
        <table>
    </HeaderTemplate>
    <ItemTemplate>
        <tr>
            <td>
                <strong><%# DataBinder.Eval(Container.DataItem, "Name" ) %></strong>
            </td>
        </tr>
        <tr>
            <td>
                <asp:Button ID="btnAddArticle" runat="server" CssClass="smallbutton" Text="<%$ Resources:Online, Form_Order_Button_AddArticle %>" CausesValidation="False" UseSubmitBehavior="true" />                                
            </td>
        </tr>
    <FooterTemplate>
        </table>
    </FooterTemplate>
</asp:Repeater>



Nu had ik het idee om, in plaats van x MPE's te generen, één MPE buiten de repeater te zetten en te gebruiken. Echter moet je een TargetControlID opgeven. Deze is echter dan voor 100+ knoppen verschillend.
Of kan ik door een druk op die knop een bepaald event throwen waardoor die MPE werkt?

Iemand ideeen?

[ Voor 0% gewijzigd door PdeBie op 26-10-2010 14:47 . Reden: bedrijfsnaam verwijderd ]


Acties:
  • 0 Henk 'm!

  • CodeCaster
  • Registratie: Juni 2003
  • Niet online

CodeCaster

Can I get uhm...

https://oneerlijkewoz.nl
Het ergste moet nog komen / Het leven is een straf / Een uitgestrekte kwelling van de wieg tot aan het graf


Acties:
  • 0 Henk 'm!

  • Cloud
  • Registratie: November 2001
  • Laatst online: 07-07 10:46

Cloud

FP ProMod

Ex-moderatie mobster

Je zult inderdaad één MPE moeten aanmaken en deze gebruiken voor alle Repeater-elementen. Een MPE voor elk Repeater-element genereert een gruwelijke hoeveelheid HTML, dus het is logisch dat de boel dan niet vooruit te branden is. TargetControlID is inderdaad verplicht, maar het volstaat hier om een willekeurig clickable element op te geven. Dit hoeft zeker niet het control te zijn wat de MPE triggert (maar bijv. een met CSS verborgen button).

Je kunt de MPE vanuit de serverside (MPEnaam.Show()) gaan tonen, maar ook vanuit javascript (en dus clientside). Hangt er dus even vanaf of je een postback wilt of niet en dat hangt weer af van hoe je applicatie verder in elkaar steekt. :)

Never attribute to malice that which can be adequately explained by stupidity. - Robert J. Hanlon
60% of the time, it works all the time. - Brian Fantana


Acties:
  • 0 Henk 'm!

  • PdeBie
  • Registratie: Juni 2004
  • Laatst online: 09:31
Yup, hier kan ik wel wat mee. Dank je :)
Cloud schreef op dinsdag 26 oktober 2010 @ 14:53:
Je zult inderdaad één MPE moeten aanmaken en deze gebruiken voor alle Repeater-elementen. Een MPE voor elk Repeater-element genereert een gruwelijke hoeveelheid HTML
Daar ben ik inderdaad achter gekomen :F

Ik heb het voorbeeld van CodeCaster even bestudeerd en daar stond inderdaad een soortgelijke oplossing in als jij opsomt.

Heb dan ook de MPE buiten de repeater gelaten en de MPE.Show(), roep ik aan op het Click event van de button. Nu nog even kijken of we dat naar de Client-side kunnen krijgen, want dat scheelt weer een call naar de server :)

Dank voor de hulp tot nog toe.
Kan het topic nog open blijven voor het geval ik vervolg vragen krijg?

Acties:
  • 0 Henk 'm!

  • Cloud
  • Registratie: November 2001
  • Laatst online: 07-07 10:46

Cloud

FP ProMod

Ex-moderatie mobster

pdebie schreef op dinsdag 26 oktober 2010 @ 15:03:
[...]

Heb dan ook de MPE buiten de repeater gelaten en de MPE.Show(), roep ik aan op het Click event van de button. Nu nog even kijken of we dat naar de Client-side kunnen krijgen, want dat scheelt weer een call naar de server :)
Dat is inderdaad de beste manier. :)
Dank voor de hulp tot nog toe.
Kan het topic nog open blijven voor het geval ik vervolg vragen krijg?
Topics worden hier in principe niet gesloten, tenzij er echt iets mis is met het topic. Dus daar hoef je volgens mij niet bang voor te zijn.

Never attribute to malice that which can be adequately explained by stupidity. - Robert J. Hanlon
60% of the time, it works all the time. - Brian Fantana


Acties:
  • 0 Henk 'm!

  • PdeBie
  • Registratie: Juni 2004
  • Laatst online: 09:31
krijg het nog niet helemaal voor elkaar om het clientSide af te handelen.

de situatie is t.o.v. de eerste post aangepast.

Ik heb een repeater met daarin de artikelen en voor elk artikel een eigen knop
Buiten deze repeater staat de MPE en het Panel wat getoond moet worden op het moment van openen.
Dit ziet er als volgt uit:

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<asp:Button ID="btnAddArticle" runat="server" CssClass="smallbutton" 
Text="<%$ Resources:Online, Form_Order_Button_AddArticle %>" 
CausesValidation="False" OnClientClick="ShowModalPopup()" />

<ajax:ModalPopupExtender ID="mpeAddArticle" runat="server" 
OkControlID="btnOK" CancelControlID="btnSkip" 
TargetControlID="btnHiddenTrick" PopupControlID="Panel1" 
BehaviorID="mpeAddArticleBehavior" DropShadow="true" />

<asp:Panel ID="Panel1" runat="server" CssClass="dontdisplay">
    <span class="dialog_front">
        <asp:Literal ID="liDialogTitle" runat="server" Text="<%$ Resources:Online, Form_Order_Dialog_Title %>" />
        <br />
        <asp:TextBox ID="tbDialog" runat="server" TextMode="MultiLine" Columns="42" Rows="5" />
        <asp:Button ID="btnOK" runat="server" Text="Opslaan" OnClick="btnOK_Click" />
        <asp:Button ID="btnSkip" runat="server" Text="Overslaan" OnClick="btnSkip_Click" />
    </span>
</asp:Panel>



Op de ClientClick roep ik de functie ShowModalPopup() aan.
code:
1
2
3
function ShowModalPopup() {
        $find("mpeAddArticleBehaviour").show();
    }


Als ik een alert() plaats in de functie ShowModelPopup, zie ik dat hij keurig afgaat. Echter crashed het script op de $find("mpeAddArticleBehaviour").
Het item blijft null.

Enig idee???

extra info: deze gehele functionaliteit (incl. repeater etc.) staan binnen een usercontrol.

Acties:
  • 0 Henk 'm!

  • L-VIS
  • Registratie: April 2005
  • Laatst online: 09-07 17:08
Volgens mij is mpeAddArticleBehaviour een niet bestaand element op jouw pagina. Dit zou moeten lukken met ClientId.

Acties:
  • 0 Henk 'm!

  • PdeBie
  • Registratie: Juni 2004
  • Laatst online: 09:31
L-VIS schreef op dinsdag 26 oktober 2010 @ 15:56:
Volgens mij is mpeAddArticleBehaviour een niet bestaand element op jouw pagina. Dit zou moeten lukken met ClientId.
mpeAddArticleBehavior is het BehaviourID van m'n MPE. Dit zou toch moeten werken?

Acties:
  • 0 Henk 'm!

  • Cloud
  • Registratie: November 2001
  • Laatst online: 07-07 10:46

Cloud

FP ProMod

Ex-moderatie mobster

Ik zie in je code staan: 'mpeAddArticleBehavior' en in je javascript 'mpeAddArticleBehaviour'. Is dat een typfout of is dat daadwerkelijk de bug? ;) Irritant, dat Amerikaans Engels en Brits Engels.

En anders zou ik het voor de zekerheid toch even proberen met ClientID. Al zou het eigenlijk wel moeten werken via BehaviorID

Never attribute to malice that which can be adequately explained by stupidity. - Robert J. Hanlon
60% of the time, it works all the time. - Brian Fantana


Acties:
  • 0 Henk 'm!

  • PdeBie
  • Registratie: Juni 2004
  • Laatst online: 09:31
Cloud schreef op dinsdag 26 oktober 2010 @ 16:15:
Ik zie in je code staan: 'mpeAddArticleBehavior' en in je javascript 'mpeAddArticleBehaviour'. Is dat een typfout of is dat daadwerkelijk de bug? ;) Irritant, dat Amerikaans Engels en Brits Engels.
dat was een typo in m'n code, maar na correctie bleek dit niet de oorzaak.
Wat de oorzaak was, was dat de button btnHiddenTrick (het verborgen TargetControlID) niet gerenderd werd. Dit kwam omdat de property Visible op false stond.
Door deze property weg te halen en een div om de knop te zetten die middels css hidden was werd hij wel gerenderd, maar dan als volgt:
code:
1
2
3
<div style="visibility: hidden; display: none;">
... button ...
</div>


Echter loop ik nu weer tegen het probleem dat de MPE na een aantal seconden automatisch weer verdwijnt.

Zo blijf ik bezig haha :+

Acties:
  • 0 Henk 'm!

  • R4gnax
  • Registratie: Maart 2009
  • Laatst online: 04-07 15:01
Met het soort variable namen als "btnHiddenTrick" weet je eigenlijk al dat wat je aan het bouwen bent een WTF in wording is.

Aangezien je tegen problemen aan blijft lopen zou ik zeggen: dump de AjaxToolkit gewoon. Je zou zeker niet de eerste zijn. Sterker nog: de library is door Microsoft zelf óók aan de kant geschoven. Zeker voor high-end, high performance doeleinden (zoals online winkels, bijvoorbeeld) is het een PitA om mee te werken.

Webpagina's zijn van nature stateless. Probeer dan ook niet allerlei navigatie logica in één pagina te frotten.
Maak je popup een nieuwe pagina en maak de knopjes die die popup moeten openen gewoon met gestylde <a> tags die bijv. een marker relatie 'dialog' hebben.

Vervolgens gebruik je (voor mensen die javascript niet uit hebben staan) jQuery met bijvoorbeeld de jQuery UI dialog component om die tweede pagina als een popup op de eerste te tonen.
JavaScript:
1
2
3
4
5
6
7
$("ul.products")
  .delegate("a[href][rel~=dialog]", "click", function(event){
    event.preventDefault();
    $("<div></div>")
      .load($(this).attr("href"))
      .dialog();
  });
Pagina: 1