disclaimer: this article covers the most powerful links in IML, when action ( direct, ajax, submit ) is performed and findings (with or with no template) are in DOM-element. This method has appeared in different examples in other articles, but today I’m going to make a review of all possibilities of this links in the Incoding Framework context
Note: article code examples are available on GitHub.
The first unit of our links is Do. It may seem to be a “noise”. But when you understand all aspects of its work that influence on browser event service it will become clear that:- Do ( sandbox ) - does not influence on behavior
- DoWithPreventDefault ( sandbox ) -cancels event, nullifying it but does not stop continuing to spread the event.
- DoWithStopPropagation – stops continuing event spreading (propagation) but does not cancel the event.
- DoWithPreventDefaultAndStopPropagation - cancels and annuals event and stops continuing spreading (propagation) event.
- Success - json объект { data:setData, success:true, redirectTo:string.Empty }
IncodingResult.Success(someData);примечание: someData может быть null, тогда результат просто сигнализирует об удачном завершении action
- Error - json object{ data:setData, success:false, redirectTo:string.Empty }
IncodingResult.Error(someData);Note: someData could be null. In this case the result just gives a signal about successful action completion.
- RedirectTo - json object{ data:null, success:true, redirectTo:someUrl }
IncodingResult.RedirectTo(url)Note: if after realization of any ( Ajax, Submit or etc ) action as the result bring back redirectTo, window.location = url actuates on the client
Each type-result puts back call (On callback ). There is a comparison table below
[table caption="Compare incoding result"] Result,On Success,On Complete,On Error,On Begin,On Break IncodingResult.Success,Yes,Yes,No,Before Action,No IncodingResult.Error,No,Yes,Yes,Before Action,No IncodingResult.RedirectTo,No,No,No,Before Action,No [/table]
[wpspoiler name="Integration with Controller" ]Factory methods IncodingResult are low-level, therefore it’s better to use methods from basic IncControllerBase class
- IncJson– is an alternative to Success
[HttpGet] public ActionResult FetchContacts() { return IncJson(GetContacts()); }
- IncView - realize render View in line and brings back through IncodingResult.Success
[HttpGet] public ActionResult Contact() { return IncView(GetContacts().FirstOrDefault()); }Note: IncView works by an algorithm
- IncPartialView–is an analog to IncView, but with a chance to show the way to View
[HttpGet] public ActionResult Contact() { return IncPartialView("NewViewName",GetContacts().FirstOrDefault()); }
- IncRedirect – is an alternative to RedirectTo
[HttpGet] public ActionResult RedirectTo(string url) { return IncRedirect(url); }
- IncRedirectToAction – redirect on the concrete Action in Controller
[HttpGet] public ActionResult RedirectTo() { return IncRedirectToAction("Action","Controller"); }[/wpspoiler]
How to get data?
- Direct ( sandbox ) – is more often used as free action, but supports a possibility to inform
Html.When(JqueryBind.InitIncoding) .Do() .Direct(IncodingResult.Success(@<span> Direct content </span>)) .OnSuccess(dsl => // some code) .AsHtmlAttributes() .ToDiv()Note: Error, Redirect could be used as data
[wpspoiler name="Scenario" ]
@(Html.When(JqueryBind.InitIncoding) .Do() .Direct(IncodingResult.Success(Model.Contacts)) .OnSuccess(dsl =>dsl.Self().Core().Insert.WithTemplateByUrl(urlTemplate).Html()) .AsHtmlAttributes() .ToDiv())Note: script is used if client template, but data are got Ajax
@(Html.When(JqueryBind.InitIncoding) .Do() .Direct(IncodingResult.Success(@<span> Static content </span>)) .OnSuccess(dsl => dsl.Self().Core().Insert.Html()) .AsHtmlAttributes() .ToButton("Insert html"))Note: the script is used, if it is necessary to set in data, that are permanent (empty line setting in, adding form elements, etc.)
[/wpspoiler]
- Ajax ( sandbox ) - request to the server
Html.When(JqueryBind.InitIncoding) .Do() .Ajax(options => { options.Url = Url.Action("Contact", "Data"); options.Type = HttpVerbs.Get; }) .OnSuccess(dsl => // some code) .AsHtmlAttributes() .ToDiv()Note: AjaxGet, AjaxPost is “named” version of Ajax
- Submit On ( sandbox) – send mentioned form through ajax ( requires connection to jquery form )
@using (Html.BeginForm("PostContact", "Data")) { <input type="text" name="Value"> @(Html.When(JqueryBind.Click) .DoWithStopPropagation() .SubmitOn(r=> r.Self().Closest(HtmlTag.Form)) .OnSuccess(dsl => // some code) .AsHtmlAttributes() .ToInput(HtmlInputType.Submit,"Post" )) }Note: this example shows a script, when Submit is realized on behalf of button. In this case as event service we choose Stop Propagation to stop event progress “Click” above (up to form)
- Submit – is similar to SubmitOn, but has no possibility to indicateform, and always sends a nearest (closest ) form in the hierarchy Dom elements or self if it is form
@using (Html.When(JqueryBind.Submit) .DoWithPreventDefault() .Submit() .OnSuccess(dsl => // some code) .AsHtmlAttributes(new { action = Url.Action("PostContact", "Data"),method="POST" }) .ToBeginTag(Html, HtmlTag.Form)) { <input type="text" name="Value"> <input type="submit" value="Post"> }Note: example shows a script, when form intercepts “Submit” event and further realizes Submit action, that’s why as event service we choose Prevent Default to annual form send by standard browser methods
- Events (sandbox ) – getting data from event, realization consists of two elements:
- The source– “throws” data through trigger
@(Html.When(JqueryBind.InitIncoding) .Do() .AjaxGet(Url.Action("Contact", "Data")) .OnSuccess(dsl => dsl.WithId(eventContainerId).Core().Trigger.Incoding()) .AsHtmlAttributes() .ToDiv())Note: any of them could be used as Action
- The receiver –the element, which the invoke is directed at.
@(Html.When(JqueryBind.None) .Do() .Event() .OnSuccess(dsl => dsl.Self().Core().Insert.Html()) .AsHtmlAttributes(new { id = eventContainerId }) .ToDiv())Note: work with data is constricted as with other Action
Events by itself has no sense, but together with Where allows building up complex scripts, e.g. chat window
[wpspoiler name="Sample" ]
The term: on a single page N-th amount of chat windows could be opened. They are tied up with chosen contact, where messages are shown.
Decision 1: each window on the base of its Id (or other concrete) requests messages on Ajax
@{ Func<string,MvcHtmlString> createWindow = (id) => { return Html.When(JqueryBind.None) .Do() .AjaxGet(Url.Action("FetchContacts", "Data",new {Id = id})) .OnSuccess(dsl => { string urlTemplate = Url.Dispatcher().Model(new TableContactTmpl { IsShowInfo = false }) .AsView("~/Views/Template/Table_Contact_Tmpl.cshtml"); dsl.Self().Core().Insert.WithTemplateByUrl(urlTemplate).Html(); }) .AsHtmlAttributes(new { @class="window col-lg-2" }) .ToDiv(); }; } @createWindow("1") @createWindow("2") @createWindow("3") @createWindow("4")
Problem: as the number of windows increases, the number of requests on the server would grow, which may result in:
- Overfill maximum limit of browser requests and there will be a delay between requests
- Load the asp.net pool
@(Html.When(JqueryBind.InitIncoding) .Do() .AjaxGet(Url.Action("FetchContacts", "Data")) .OnSuccess(dsl => dsl.WithClass("window").Core().Trigger.Incoding()) .AsHtmlAttributes() .ToDiv())Note: now there is only one request, but we „add“ data to all elements with “window” class, but windows knows which Id should be used for filtering.@{ Func<string, MvcHtmlString> createWindow = (id) => { return Html.When(JqueryBind.None) .Do() .Event() .Where(r => r.Id == id) .OnSuccess(dsl => { string urlTemplate = Url.Dispatcher().Model(new TableContactTmpl { IsShowInfo = false }) .AsView("~/Views/Template/Table_Contact_Tmpl.cshtml"); dsl.Self().Core().Insert.WithTemplateByUrl(urlTemplate).Html(); }) .AsHtmlAttributes(new { @class="window col-lg-2" }) .ToDiv(); }; } @createWindow("1") @createWindow("2") @createWindow("3") @createWindow("4")
Структурное изображение решения
[/wpspoiler]
- Ajax Hash– is an analog of Submit, not for form, but for
AjaxGet(Url.Action("Action", "Controller",new { Id = Selector.Incoding.HashQueryString("id"), First = Selector.Incoding.HashQueryString("first"), Last = Selector.Incoding.HashQueryString("last"), }))Note: all parameters are obtained from hash, but we must indicate each of them
Example with Ajax Hash
AjaxHashGet(Url.Action("Action","Controller"))
Note: now the example works similar to Submit form ( serialization hash ), but collect parameters from hash
All “action”, except Direct and Evetns , works with ajax, that’s why the question could come up: in what case which to use- If you fill N-th amount of input, put in form and further actionSubmit
- If search parameters are kept in hash, use action AjaxHash
- In all other cases could be realized with actionAjax
@(Html.When(JqueryBind.Click) .Do() .AjaxPost(Url.Action("Change","Status",new {New = Status.Approve})) .OnSuccess(dsl => //some code) .AsHtmlAttributes() .ToButton("Change"))
@Html.DropDownList("test", new SelectList(new[] { }), Html.When(JqueryBind.InitIncoding) .Do() .AjaxGet(Url.Action("Fetch", "Country")) .OnSuccess(dsl => //some code ) .AsHtmlAttributes())And many other tasks (content for dialog, record deletion)
[/wpspoiler]
This is one of a set of executables that are available under On callback, that is why this is not an obligatory element of a line, but most of scripts are aimed to insert findings in Dom element. “Insert” repeatedly figured in examples from other articles, but now we are going to examine the work of this executable better- Content - controller brings back IncView or IncPartialView
[HttpGet] public ActionResult Contact() { return IncView(new ContactVm()); }Note: IncView will look for Contact.cshtml in file View/$Controller$
Html.When(JqueryBind.InitIncoding) .Do() .AjaxGet(Url.Action("Contact", "Data")) .OnSuccess(dsl => dsl.Self().Core().Insert.Html()) .AsHtmlAttributes() .ToDiv()
Html.When(JqueryBind.InitIncoding) .Do() .AjaxGet(Url.Dispatcher().Model(new ContactVm()).AsView("~/Views/Template/Contact.cshtml")) .OnSuccess(dsl => dsl.Self().Core().Insert.Html()) .AsHtmlAttributes() .ToDiv()
Note: realization on mvd dispense writing of controller
[/wpspoiler]
- Object - controller brings back IncJson
[HttpGet] public ActionResult FetchContact() { return IncJson(new ContactVm()); }
@(Html.When(JqueryBind.InitIncoding) .Do() .AjaxGet(Url.Action("FetchContact", "Data")) .OnSuccess(dsl => dsl.Self().Core().Insert.WithTemplateByUrl(urlTemplate).Html()) .AsHtmlAttributes() .ToDiv())note: urlTemplate must return IncView
@(Html.When(JqueryBind.InitIncoding) .Do() .AjaxGet(Url.Dispatcher().Query(new GetContactQuery()).AsJson()) .OnSuccess(dsl => dsl.Self().Core().Insert.WithTemplateByUrl(urlTemplate).Html()) .AsHtmlAttributes() .ToDiv())[/wpspoiler] Note: each method has its analog in jquery All examples were constructed on one model, but there are could be other scripts when findings are “container”. To this effect in Insert is a chance to show with which part of model works through.
dsl.WithId(newsContainerId).Core().Insert.For<ContactVM>(r => r.News).WithTemplateByUrl(urlTemplate)).Html();Note: as T for For must be showed a model that is in data
[wpspoiler name="Examples of scripts " ]
Note: each method has its analog in jquery
Condition: by Id records get its model and update form fields
Decision 1: after loading to update the hole form, built it again, but sometimes this can complicate this task, of form has extra elements.
Decision 2: after loading to update only necessary fields
@(Html.When(JqueryBind.Click) .Do() .AjaxGet(Url.Action("FetchContactById", "Data", new { id = each.For(r => r.Id) })) .OnSuccess(dsl => { dsl.With(r => r.Name(s => s.Last)).Core().Insert.For<ContactVm>(r => r.Last).Val(); dsl.With(r => r.Name(s => s.First)).Core().Insert.For<ContactVm>(r => r.First).Val(); dsl.With(r => r.Name(s => s.City)).Core().Insert.For<ContactVm>(r => r.City).Val(); }) .AsHtmlAttributes() .ToButton("Show info"))
Note: you can use reflection and build Insert.For dynamically
Condition: update N-th amount of elements by different dataDecision 1: each element makes a request of its data, but it leads to increase load in server and slow page loading because of large amount of isochronic
Note: partially this problem could be solved by Ajax Asyc in false installation. In this case a page would be loaded by pieces. That is also permissible
Decision 2: one element load all data than through For “pointwise” to update
Html.When(JqueryBind.InitIncoding) .Do() .AjaxGet(Url.Action("FetchComplex", "Data")) .OnSuccess(dsl => { dsl.WithId(newsContainerId).Core().Insert.For<ComplexVm>(r => r.News).WithTemplateByUrl(urlTemplateNews).Html(); dsl.WithId(contactContainerId).Core().Insert.For<ComplexVm>(r => r.Contacts).WithTemplateByUrl(urlTemplateContacts).Html(); }) .AsHtmlAttributes() .ToDiv()
Note: for each For you can use its template
[/wpspoiler]
Method of Executor ( executable ) Trigger looks like Form ethos, but it coupled with action events and let delegate data to other elements but don’t make actions. Example:Insert For ( sandbox )
dsl.WithId(newsContainerId).Core().Insert.For<ComplexVm>(r => r.News).WithTemplateByUrl(urlTemplateNews).Html();
Trigger For ( sandbox )
- The source
dsl.WithId(newsContainerId).Core().Trigger.For<ComplexVM>(r => r.News).Incoding();
- The receiver
Html.When(JqueryBind.None) .Do() .Events() .OnSuccess(dsl => dsl.WithId(newsContainerId).Core().Insert.WithTemplateByUrl(urlTemplateNews).Html()) .AsHtmlAttributes() .ToDiv()Note: realization with Events needs extra element
Decision with Trigger looks more complicated, therefore if you need only put different parts of one model it would be better to use Insert For, but possibility of Where for Events lets realize scripts that couldn’t be solved with Insert
This is the 1st part of planed cycle of articles about different links, but in fact it’s rather difficult to examine all possible tasks because IML is not so flexible. But this fact let us group in a completely different variations for complex scriptsI’ve picked out fundamental:
- Do, Action, Insert
- When, Trigger
- Submit Form
- Search hash
P.S. if somebody has a script that he wants to be examined, how to solve in Incoding Framework, leave it in comments and I’ll make an article.