Can you use #model like #ViewBag? - asp.net-mvc-3

So I have a question about model in ASP.NET MVC. I know I can use a ViewBag like this: <h1> #ViewBag.Question </h1> and it would display the text in #ViewBag.Question. Can I use #model in the same way? I have tried using it in the same context, <h1> #Model.Question </h1> but the view throws an error. How can I display the text of a model property inside an html element?

Yes, #Model can be used in the same way as #ViewBag

Related

Bind raw html in Aurelia

Using Aurelia, I want to fill an <div> with contents of viewmodel property (lets call it htmlText) which contains html text, and I was using
<div>
${htmlText}
</div>
However, this encodes html so, instead of i.e. having paragraph or link, all tags are escaped so html can be seen as source.
Is there out of the box binder to do this?
You can accomplish this using the innerhtml binding like so:
<div innerhtml.bind="htmlText"></div>

thymeleaf spring standard dialect: using template

Hello I have some problems with templating pages.
I am returning from controller a view called list:
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" layout:decorator="layout/template">
<div layout:fragment="pageContent">
<p>LIST</p>
</div>
</html>
And I would like to put this into template where I have a lot of html stuff and:
<div layout:fragment="pageContent">Demo static page content</div>
But I am getting in web browser only list view.
How to put one view returned from controller to template using SpringStandardDialect?
So if i understand correctly, you want to inject that fragment which is called pageContent into some other html page (lets call it main.html for sake of it.
First thing to do is change the div in list to the following:
<div th:fragment="pageContent">
<p>LIST</p>
</div>
then in your main.html you would call the fragment via:
<div th:include="list::pageContent"></div>
or
<div th:replace="list::pageContent"></div>
Btw "list::pageContent" indicates that its in base folder, if its located in folder called example then it would be "example/list:pageContent".
here is the great example on Thymeleaf website: http://www.thymeleaf.org/doc/usingthymeleaf.html#including-template-fragments
Hope this helps, if not let me know.

What is ColdFusion Model Glue's equivalent to ASP.NET MVC 3's #section?

In ASP.NET MVC 3, you can have an #section within a view:
#section SideBar {
<p>Some content</p>
<p>Some more content</p>
}
<p>Body content</p>
Then in the master view, you would use this to render it:
<div id="sidebar">
#RenderSection("SideBar", false)
</div>
#RenderBody()
What would be the ColdFusion equivalent of this in the Model Glue framework? I know I can set simple variables in the view:
<cfset event.setValue("section", "Tables")>
Then use them in the master template like so:
<cfif event.exists("section")><h3>#event.getValue("section")#</h3></cfif>
But this only works well for one-liners and simple strings. What I'd like to do is include an entire HTML block. What is the best way of accomplishing this? I think this would work in theory:
<cfsavecontent variable="sidebar">
<p>Some content</p>
<p>Some more content</p>
</cfsavecontent>
<cfset event.setValue("sidebar", sidebar)>
But I was wondering if there's a better way of doing it.
Edit:
In response to Adam Cameron's answer, Model Glue, from what I can tell, only supports the ability to combine separate files into one template:
SideBar.cfm:
<p>Some content</p>
<p>Some more content</p>
Page.cfm:
<p>Body content</p>
ModelGlue.xml:
<event-handler name="page.text">
<views>
<include name="sidebar" template="SideBar.cfm"/>
<include name="body" template="Page.cfm"/>
<include name="main" template="main.cfm"/>
</views>
</event-handler>
main.cfm:
<cfoutput>#viewCollection.getView("sidebar")#</cfoutput>
<cfoutput>#viewCollection.getView("body")#</cfoutput>
I need to be able to declare the sidebar content within the page.cfm view. The thought here is that there will be a div somewhere in the main template that allows for a small HTML snippet, say an image with a text description and a link, which any view can populate. It wouldn't make sense to have something like Page1.cfm and Page1SidebarContent.cfm, Page2.cfm and Page2SidebarContent.cfm, etc...
ModelGlue doesn't support what you want to do out of the box. However its easy enough to achieve using Peter's suggestion and ModelGlue helpers for encapsulation.
Create a new cfc, call it PageFragment.cfc and drop it in to your ModelGlue helpers directory.
// untested!
component name="PageFragment" {
public boolean function exists(string name) {
return structkeyexists(request.subcontent, arguments.name);
}
public string function get(string name) {
if(exists(arguments.name)) return request.subcontent[arguments.name];
return "";
}
public void function set(string name, string value) {
request.subcontent[arguments.name] = arguments.value;
}
}
Then in your views you can do
index.cfm
<cfset helpers.PageFragment.set("sidebar", "<p>My sidebar content</p>") />
main.cfm
<cfif helpers.PageFragment.exists("sidebar")>
<div id="sidebar">#helpers.PageFragment.get("sidebar")#</div>
</cfif>
To avoid having to cfsavecontent all your fragments you could create a customtag that used thistag.generatedcontent and the caller scope to access your helpers.
By using helpers to encapsulate the functionality its really easy to reuse, or to change later without altering your views, for example you may want to add caching.
(Unfortunately) I haven't touched MG for ages, but I just googled the docs, as a reminder.
You need to read up on how views work, but this page of the docs summarises it succinctly:
http://docs.model-glue.com/wiki/ReferenceMaterials/ViewApi#ViewAPI
Specifically this code snippet:
<cfoutput>#viewcollection.getView("body")#</cfoutput>
It's probably a case of reading through the docs a bit, and reminding yourself about how model glue's implementation of MVC (specifically the V part, in your case!) works.
I haven't used Model-Glue nor ASP.NET MVC, but it seems what you want can be achieved like this:
In page.cfm do:
<cfsavecontent variable="Request.SubContent['ThisPage'].Sidebar">
<p>Some content</p>
<p>Some more content</p>
</cfsavecontent>
<p>Body content</p>
Then in main.cfm use:
<div id="sidebar">
<cfif StructKeyExists(Request.SubContent,PageName)
AND StructKeyExists(Request.SubContent[PageName],'Sidebar')
>
#Request.SubContent[PageName].Sidebar#
<cfelse>
#viewCollection.getView("default_sidebar")#
</cfif>
</div>
<cfoutput>#viewCollection.getView("body")#</cfoutput>
Depending on how things are structured, you might prefer to cache content in a persistent scope and/or hide it behind a couple of methods (possibly even extending Model-Glue to allow this natively; it is Open Source after all), but hopefully this gives a general idea?
I see what you mean now. I'm not sure MG will have that sort of functionality built-in because in an MVC environment, it's not really up to a view to be doing this sort of thing: you're kinda coupling controller & model stuff together in a view file. There might be a good reason for you doing this, but I wonder if it's your approach that might be your undoing here? Can you not put the "get the sidebar" stuff into the controller & have that call a model, and add in a sidebar view if needed? That'd be how I'd approach this.
That said, I know it's unhelpful having people say "I'm not going to answer your question, I'm just going to complain about it", so I'll have a look-see around and see if I can come up with something.
However given you're wanting to break-out of a MVC approach here, perhaps don't try to get MG to do this for you, just do what Peter suggests and capture a variable in the page.cfm view, stick it in a sensibly-structured struct (nice tautology, Cameron), and then look for it in the view you want to render it.

Declarative AJAX "Controls" in MVC

I want to create a reusable ajax control in MVC .NET using RAZOR.
my example is a simple ajax text box and list where the user filters the list by typing in the text box. on the first call i would render both the text box and the list using my razor view. on subsequent AJAX calls i would want to ONLY render the (now filtered) list.
idea 1: use #if statement to conditionally render code.
problem: razor does not seem to like conditionally written html. for example it errors when a <div> tag is not followed by a closing </div>.
idea 2: use #section tokens to create portions of my control and then call RenderSection within the same file as needed.
problem: razor does not allow RenderSection to call sections in the same page
i know i can conditionally render html as strings, but i wanted to take advantage of the legibility of the razor markup and keep with development protocols.
You should be able to output <div> tags in a Razor block without the corresponding </div> tag by surrounding it with <text>. The reason is that Razor uses the closing tag to know when to drag back into code-parsing mode:
#if (myCondition)
{
<text>
<div>
</text>
}
As for the Section stuff, you might be able to achieve what you want using Templated Razor Delegates, like this:
#{
Func<dynamic, object> b = #<strong>#item</strong>;
}
// ...
<span>This sentence is #b("In Bold").</span>
See Phil Haack's blog for a little more on this.

MVC wrap content with static content. UserControls?

I'm trying to wrap content with some static HTML in MVC and I'm not having any luck figuring this out. There must be an obvious solution that I'm not seeing, as this would seem like a desired feature.
In my View, I need to wrap HTML content with something:
<uc1:mc>
<p>Hello World!</p>
</uc1:mc>
That will render like:
<div class="ribbon">
<div class="left"></div>
<p>Hello World!</p>
<div class="right"></div>
</div>
With a Template like:
<div class="ribbon">
<div class="left"></div>
<%= IncomingMarkupGoesHere %>
<div class="right"></div>
</div>
The idea is to reuse html that wraps around other html.
I'm currently using two User Controls to achieve this, one with everything before and the other with everything after. Something like this:
<% Html.RenderPartial("RightRibbon_Start"); %>
Target Content...
<% Html.RenderPartial("RightRibbon_End"); %>
But this seems sloppy and isn't conducive to passing parameters that apply to HTML before and after the target content.
It's important that the content to be wrapped be allow to be written as multiple lined markup and not just a string, otherwise I would just pass the content as the Model.
What about creating helpers and passing the HTML in as an argument?
Passing html markup into an ASP.NET User Control

Resources