I am using .NET MVC4 and have created a number of PartialViews that are all used as templates. I use Backbone.js and Backbone.Marionette.js for my client-side code and have created the templates used in my Backbone Views as RAZOR PartialViews.
I created a Controller called TemplatesController that has a ChildAction and given a name of PartialView it returns the MvcHtmlString for that PartialView which is my template. I can then use the template along with Handlebars to create my View in Backbone.Marionette.
This all works great for me but I have to call the Controller action for every PartialView that exists. My list of templates is growing and I would like to not have to add a new call render the template every time to my Index View.
My question is, is there a better way to just call the Controller once and return all PartialViews that exist? Thanks for any suggestions.
Here is my Controller method
[ChildActionOnly]
public ActionResult GetTemplate(string name) {
return PartialView(name);
}
Here is a HtmlHelper Method I use to call the Controller Action
public static MvcHtmlString Template(this HtmlHelper htmlHelper, string name) {
// call ChildAction on our controller to get the HTML for this template
return htmlHelper.Action("GetTemplate", "Templates", new { name = name });
}
Here is example of how I load templates into Index or _Layout view using Helper. For each PartialView I create I add a line but I would like to remove these and do it in one line such as Html.AllTemplates or something.
#Html.Template("SiteHeader")
#Html.Template("SiteFooter")
I stripped all the content out but this would be example of what would be in each of the partial views, the main thing to note is it is wrapped inside a script tag
<script id="site-header" type="text/x-handlebars-template">
<h3>{{headertext}}</h3>
<div>{{somevalue}}</div>
</script>
Related
I am making an if check in the controller
if(validDate<DateTime.Now)
{
//TODO
}
And what I want to do is to hide a specific button in my view if this statement is true, otherwise show it. I am also using jquery in front end.
Can someone help me to manipulate the html element, the button, from the controller, example add a style class or something?
In this case I need to make the changes from the controller and not from the jquery, but I can use the jquery after if needed.
You need to use models (aka as ViewModel), #thomashaid already gave you a comment with a useful article: Views And ViewModels.
Create a class in the "Models" folder of your MVC Project. Like this:
public class MyViewModel
{
public bool ShowButton { get; set; }
}
Then in your controller, create an object of your ViewModel class and assign the corresponding value to the ShowButton property. Then pass the ViewModel to the returning view:
public ActionResult MyAction()
{
var myViewmodel = new MyViewModel();ยด
if(validDate < DateTime.Now)
{
myViewModel.ShowButton = true;
}
return View(myViewModel);
}
Finally, use razor syntax in your view to manipulate the HTML code that will be returned to the client:
#model MyViewModel
#if (Model.ShowButton)
{
<Button>now you see me</Button>
}
I'm getting used to view components in MVC 6, and I asked a similar question a few years ago about partial views. If I build a view component encapsulating a common use-case that requires its own Javascript, where do I put that Javascript? I know that it is dangerous at best to have Javascript in partial views, but it would be a lot simpler to include it in the view component, rather than in the containing view or a separate file that has to be referenced by the containing view.
For example, say I have a view component that has two drop-downs. The selection in the first drop-down determines what items appear in the second drop-down. This is easily handled in Javascript, of course, but where do I put it?
From my experience with ASP.NET 5 View Components, I would say that the best thing to do with them is to keep them isolated and in one place, so they will be easily to manage in long-term projects.
In one of my ASP.NET projects, I've developed View Components structure like this one:
View, Backend code and Model are all in one place, so when you move around the folder, you are sure that you move whole component. Moreover, when you are modyfying them, you have quick access to all of their parts.
It will be convinient to put JavaScript which is highly coupled with a component also in such structure. You can do this by simply creating the file under the component's folder, and then writing a GULP TASK that will copy JS file to wwwroot. From that point, you will be able to link that JavaScript code on component's .cshtml using standard syntax:
<script src="~/Components/yourcomponent.js"></script>
To obtain such a structure in my project, I've extended Razor, to be able to search for my component's CSHTML's in proper place. To do this, I've added this code in Startup.cs:
public partial class Startup
{
public void ConfigureServices(IServiceCollection services)
{
//non relevant code skipped
services.AddMvc().AddRazorOptions(ConfigureRazor);
}
public void ConfigureRazor(RazorViewEngineOptions razor)
{
razor.ViewLocationExpanders.Add(new ViewLocationExpander());
}
}
and the ViewLocationExpander class is:
public class ViewLocationExpander : IViewLocationExpander
{
protected static IEnumerable<string> ExtendedLocations = new[]
{
"/{0}.cshtml"
};
public void PopulateValues(ViewLocationExpanderContext context)
{
//nothing here
}
public IEnumerable<string> ExpandViewLocations(ViewLocationExpanderContext context, IEnumerable<string> viewLocations)
{
//extend current view locations
return viewLocations.Concat(ExtendedLocations);
}
}
Then, you invoke component like this (from any .cshtml view):
#await Component.InvokeAsync("NavigationComponent",new NavigationComponentModel())
I have an AngularJS application. Within that app, I am trying to load up a piece of HTML with a custom directive. My directive (in app.js) is as follows:
app.directive('mytable', function() {
return {
restrict: 'E',
templateUrl: '/mytable'
};
});
Within my HTML file (index.html) then, I just specify the custom tag.
<mytable></mytable>
The implementation details within mytable.html are just static HTML. On the routing side with Java Play, I have:
GET /mytable Application.mytable
And within my Play controllers (Application.java), I have:
public static void mytable() { render(); }
However, when I try to load a page, I get:
GET http://localhost:9000/mytable 500 (Internal Server Error)
XHR finished loading: GET "http://localhost:9000/mytable".
Upon closer inspection, within the console, I see:
Template not found
The template Application/mytable.txt does not exist.
How can I fix my code? And why is it trying to render mytable.txt instead of mytable.html, when all my other controllers in Application.java are the same and render .html files correctly?
Just a side note: http://localhost:9000/mytable does render the static content for <mytable> correctly.
Edit: this applies only to Play versions 2.x
I have the feeling that your controller's method is a bit wrong. I would rewrite this
public static void mytable() { render(); }
to:
public static Result mytable() {
ok(index.render());
}
where index is your view, render is the method you call to render this view, and your controller returns a Result (via the ok() method)
This might be quite simple but I am having difficulties with it. I have a view where I am setting a javascript variable, within that view I display a partial view using RenderPartial like so:
#{Html.RenderPartial("MyPartialView");}
I need access to a js variable set in my View, in my PartialView. Is this possible? I know there are several other ways to pass data using models but for my unique scenario it would be very helpful if I could do it this way as I am already passing a model so I can't do it that way.
Why wouldn't you pass your model into your partial view ?
anyway you can add your property to window object and use it in your partial view.
UPDATE:
What I meant was to open script tag in your view as follows :
<script>
window.test = "test value";
</script>
and use it in your partial view as follows :
<script>
alert( window.test);
</script>
BTW you can pass additional info to you partial view . Html.Partial accepts a third parameter which is viewData dictionary .
#Html.Partial("PartialViewName", yourModel, new ViewDataDictionary(){ {"AdditionalModel", value} })
and you can access it in your partial view by its name :
ViewData["AdditionalModel"]
sorry for the late response
I have a web page with a couple of view components, when I click on these components I open a simple editor for it, see image below. If I edit the text and hit enter, I would like to rerender the view component and not the hole page. Is it possible to invoke a view component using javascript to get this behaviour?
With updates, you should now be able to do this with asp.net core. You can return a ViewComponent from an IActionResult, then just call it with jQuery:
[Route("text-editor")]
public IActionResult TextEditor()
{
return ViewComponent("TextEditorViewComponent");
}
Then this can be called from your View with something as simple as this:
function showTextEditor() {
// Find the div to put it in
var container = $("#text-editor-container");
$.get("text-editor", function (data) { container.html(data); });
}
If you need to pass parameters to the ViewComponent you can do so in the IActionResult (maybe they trickle through from the View to there, to the view component, etc).
This is not possible today but you could build a standard proxy for viewcomponents if you'd like though (similarly you could build a proxy to partial views). e.g. you a catchall attribute route on an action.