Nuget csomag: www.nuget.org/packages/Multipartial
Bevezetés
Nemrégiben volt egy projektünk, amelyen nagyon kevesen dolgoztunk fejlesztők. Fontos szempont volt, hogy a webalkalmazásunknak Facebook-szerű, komplex UI-a legyen, de semmiképpen sem szerettünk volna nekiállni bonyolult kliensoldali kódot írni, ezért elhatároztuk, hogy minimalizáljuk a JavaScript mennyiségét, és lehetőleg minden html kódot a szerveroldalon renderelünk ki. Az elképzelésem az volt, hogy a Html tartalmat felszabdaljuk sok, egymásba ágyazott partial view-ra (akár egy lista egyetlen listaeleme is egy partial view lehet), ezeket view-kat frissítjuk, így mindössz annyi JavaScriptre lesz szükségünk, ami elposztolja a kérést, majd a visszakapot html snipetet egyszerűen a helyére rakja.
Az gyorsan kiderült, hogy ez a beépített ActionResult-okkal nem fog menni, ezért csináltam egy saját megoldást.
A megoldás
Készítettem egy saját AcionResult osztályt, amely segítségével egyszerre lehet a weboldalnak több, egymástól teljesen független részét frissíteni. Ennek a neve MultipartialResult lett.
Tegyük fel, hogy egy webes levelező alkalmazáson dolgozol. Amikor itt a felhasználó kiválaszt egy levelet, és rákattint a Törlés gombra, a következő dolgok történnek egyszerre:
- Az aktuális kijelölt levél eltünik a listából, és a következő jelölődik ki.
- Az Előnézet dobozban az újonnan kijelölt levél tartalma jelenik meg
- A levelek számát jelző szám megváltozik
- A böngésző címsora is megváltozik, mivel ott is fel van tüntetve az olvasatlan levelek száma
Ebben az esetben mind az email-ek listája, mind az Előnézet doboz egy-egy partial view. A levelek száma egy egyszerű szöveg a DOM-ban.
A MultipartialResult használatával a Delete gomb eseménykezelő action-ja valahogy így néz ki:
public ActionResult OnDelete(long EmailId)
{
//... does the deleting
//... creates the model for the new InboxList partial view (InboxListModel)
//... creates the model for the PreviewPane partial view (PreviewPaneModel)
//... calculates the number of the emails (EmailCount)
//... renders the browser title with the updated unread email number (BrowserTitle)
MultipartialResult result = new MultipartialResult();
result.AddView("_InboxList","InboxListDiv",InboxListModel);
result.AddView("_PreviewPane","PreviewDiv",PreviewPaneModel);
result.AddContent(EmailCount.ToString(),"EmailCountDiv");
result.AddScript(string.Format("document.title='{0}';",BrowserTitle));
return result;
}
Az AddView eredményeként az _InboxList view tartalma az InboxListDiv elemben fog megjelenni.
Az AddContent eredményeként a megadott string az EmailCountDiv-be kerül bele.
Az AddScript eredményeként a kliensoldalon lefut a megadott JavaScript.
A kliensoldalon az egyetlen teendő van, meghívni a MultipartialUpdate JS függvényt az OnSuccess eseménykezelőben:
@Ajax.ActionLink("Delete", "OnDelete", new { EmailId = Model.CurrentEmail.Id }, new AjaxOptions { OnSuccess = "MultipartialUpdate" })
vagy, Ajax formban így:
@using (Ajax.BeginForm("OnDelete",
new { EmailId = Model.CurrentEmail.Id }, new AjaxOptions { OnSuccess = "MultipartialUpdate" }))
vagy, jQuery .post vagy .ajax függvényben így:
function deleteClicked(emailId) {
$.ajax({
url: "/inbox/ondelete",
type: "POST",
data: { emailId: emailId },
success: function (result) {
MultipartialUpdate(result);
},
});
Háttér
A Multipartial működési elve nagyon egyszerű. A JsonResult osztályból van örököltetve, lerendereli a megadott view-kat stringekbe, ezeket összegyűjti, és egy json-ba csomagolva elküldi a kliensoldalra. Ott pedig egy JS függvény szépen végigmegy rajtuk, és mindegyiket a helyére rakja a DOM-ban.
Amikor a szerveroldalon összegyűjti, mindegyik megjelöli tartalom alapján:
public MultipartialResult AddView(string viewName, string containerId, object model = null)
{
views.Add(new View() { Kind = ViewKind.View,
ViewName = viewName, ContainerId = containerId, Model = model });
return this;
}
public MultipartialResult AddContent(string content, string containerId)
{
views.Add(new View() { Kind = ViewKind.Content, Content = content, ContainerId = containerId });
return this;
}
public MultipartialResult AddScript(string script)
{
views.Add(new View() { Kind = ViewKind.Script, Script = script });
return this;
}
Mikor az action visszatér az ActionResult osztállya, az Mvc keretrenszer meghívja az ExecuteResult függvényt, amely elkészíti ezt a json-t:
public override void ExecuteResult(ControllerContext context)
{
List<object> data = new List<object>();
foreach (var view in views)
{
string html = string.Empty;
if (view.Kind == ViewKind.View)
{
//view result
html = RenderPartialViewToString(mController, view.ViewName, view.Model);
data.Add(new { updateTargetId = view.ContainerId, html = html });
}
else if (view.Kind == ViewKind.Content)
{
//content result
html = view.Content;
data.Add(new { updateTargetId = view.ContainerId, html = html });
}
else if (view.Kind == ViewKind.Script)
{
//script result
data.Add(new { script = view.Script });
}
}
Data = data;
base.ExecuteResult(context);
}
A view-k string-be renderelésébe most inkább nem mennék bele...
A kliensoldalon már csak egy kis egyszerű JS függvényre van szükség, amely megkapja ezt a json-t, végigmegy rajta és mindegyik elem esetében frissíti a DOM-t, vagy futtatja a JS-t.
function MultipartialUpdate(views) {
for (v in views)
if (views[v].script) {
eval(views[v].script);
}
else {
$('#' + views[v].updateTargetId).html(views[v].html);
}
return false;
}
Remélem, van még rajtam kívül valaki, aki ezt hasznosnak találja... :)
Betway Casino | Free Play | No deposit | $25 Free + 150 FS
VálaszTörlésPlay the latest games with Betway Casino 12bet | Get $25 planet win 365 Free + 150 FS or 150 FS Bonus at Gold Casino - Instant Play! betway
Sports betting is authorized in a majority of the states within the US. On this web page, you'll find out the place you can to|you possibly can} place a sports activities wager online within the USA. A money line wager is a wager on a particular group to win a contest without a a|with no} point unfold to cover. The favourite (-) and underdog (+) are given odds primarily based on a $100 wager. If you ever hear 메리트카지노 the term “straight bet” it's referring to a particular wager on a sports activities contest with a win or loss on the wager decided by a degree unfold, money line or total (over/under). Ted Dahlstrom works within the Seattle area as an Evergreen & Commercial Content Manager for Better Collective.
VálaszTörlés