views:

138

answers:

3

I have a strongly typed view and want to use it in an NHaml page.

With the WebForms engine I would describe the ViewData type in the <%@ Page%> directive or in the codebehind file.

How would I go about that in NHaml?

+1  A: 

On this page there's a patch (search for NHaml) to do this. I don't know if it works. This requires NHaml from MvcContrib.

Patch for NHaml View Engine to upgrade it to work with MVC Preview 3 Included a Model property on NHamlView's to allow strongly typed access to the model data in the ViewDataDictionary as the interface property is non generic and we like to strongly type our ViewData access within Views .. e.g. ViewData.Property under Preview 2 would become Model.Property under Preview 3 Applied May 30 2008: Applied in revision 375.

queen3
Preview 3? that's a long time ago! Why hasn't it been included so far? I'll have a look at it anyway, thanks
borisCallens
+1  A: 

Boris

If I understand correctly you just want to have a strong typed nhaml view?

If this is the case there is a sample project in svn that does this. Have a look at

http://nhaml.googlecode.com/svn/trunk/src and the NHaml.Samples.Mvc.CSharp project

And here is some extracted code

Controller

public class ProductsController : Controller
{
    private readonly NorthwindDataContext northwind = new NorthwindDataContext(
        ConfigurationManager.ConnectionStrings["NorthwindConnectionString"].ConnectionString );


    public ActionResult Edit( int id )
    {
        var viewData = new ProductsEditViewData { Product = northwind.GetProductById( id ) };

        viewData.Categories = new SelectList( northwind.GetCategories(), "CategoryID", "CategoryName", viewData.Product.CategoryID );
        viewData.Suppliers = new SelectList( northwind.GetSuppliers(), "SupplierID", "CompanyName", viewData.Product.SupplierID );

        return View( "Edit", viewData );
    }

}

View

%h2= ViewData.Model.Product.ProductName
%form{action='#{Url.Action("Update", new { ID=ViewData.Model.Product.ProductID \})}' method="post"}
  %table
    %tr
      %td Name:
      %td= Html.TextBox("ProductName", ViewData.Model.Product.ProductName)
    %tr
      %td Category:
      %td= Html.DropDownList("CategoryID", ViewData.Model.Categories, (string)null)
    %tr
      %td Supplier:
      %td= Html.DropDownList("SupplierID", ViewData.Model.Suppliers, (string)null)
    %tr
      %td Unit Price:
      %td= Html.TextBox("UnitPrice", ViewData.Model.Product.UnitPrice.ToString())
  %p
  - Html.RenderPartial(@"_Button")

View Model

public class ProductsEditViewData
{
    public Product Product { get; set; }
    public SelectList Suppliers { get; set; }
    public SelectList Categories { get; set; }
}

Hope that helps

Simon
Well, almost. I'm actually hoping it will work with the new asp.net mvc 2 LabelFor() and other XFor Html helpers.As I gather, from your and others' answer I don't need to put a directive anywhere. I didn't even try if it would just work so I'll give it a shot later on.
borisCallens
+1  A: 

I would describe the ViewData type in the <%@ Page%> directive or in the codebehind file.

How would I go about that in NHaml?

You don't need to do it. You can just use the Model without specifying its type and it will work. For example:

%h2= Model.PageTitle
  %p= Model.UserMessageOrSomething

This is because the NHAML view gets compiled. So when all the properties on the Model are correct (names, types etc) the view will be compiled (as source code would).

Dmytrii Nagirniak
True? Cool. I think this does create a barrier for making an auto complete function in the future though :S
borisCallens
Actually lanwin already has a solution for auto completion :)
Simon