2011-08-02 67 views
1

我的模型是基於一個抽象基類,它看起來像這樣:如何創建一個類似Html.DisplayFor一個HTML輔助方法,將看在自定義文件夾

  • InsurancePolicy(抽象基類所有政策)
    • VehicleInsurancePolicy
      • AbcInsurancePolicy
      • DefInsurancePolicy
    • HomeInsurancePolicy
    • LifeInsurancePolicy
    • ...等

在控制器我有平時detalis /列表情景下面的代碼:

public ActionResult Details(int id) { 
     // actual type is one of the concrete implementations 
     InsurancePolicy policy = _repository.Get(id); 
     return View(policy); 
    } 

    public ActionResult List() { 
     // a list of concrete implementations 
     IList<InsurancePolicy> policies = _repository.GetLatest(20); 
     return View(policies); 
    } 

的Details.chstml只調用@Html.DisplayForModel(),ASP.NET MVC實際上從中選擇正確的局部視圖Shared/DisplayTemplates根據實際類型(其中一個子類)。此外,如果無法找到具有該名稱的視圖,則會回退到基類模板InsurancePolicy.cshtml。例如,它會爲AbcInsurancePolicy模型選擇VehicleInsurancePolicy.cshtml,因爲沒有找到AbcInsurancePolicy.cshtml;對於HomeInsurancePolicy,它將選擇默認InsurancePolicy.cshtml,因爲在DisplayTemplates文件夾中沒有HomeInsurancePolicy.cshtml。它允許我添加其他InsurancePolicy子類型,而無需首先創建顯示模板。

我想有一個列表視圖類似的行爲。在List.cshtml Razor視圖我只會遍歷我的項目,並呼籲像Html.ListItemFor(...)

<ul> 
@foreach (var policy in Model) { 
    @Html.ListItemFor(_ => policy) 
} 
</ul> 

如何創建一個Html.ListItemFor HTML輔助,將尋找到一個ListItemTemplates文件夾和行爲完全一樣Html.DisplayFor? 有沒有其他方法可以做到這一點?

備註: Html.DisplayFor(m => m.Property, templateName)不起作用,它必須根據項目類型選擇模板名稱,遞歸回退到基類模板,直到找到某種東西。

回答

0

工作方式是基於視圖引擎中定義的一組視圖位置找到模板。

你可以做的是從RazorViewEngine繼承和重寫

public override ViewEngineResult FindPartialView(
     ControllerContext controllerContext, 
     string partialViewName, 
     bool useCache) 

這種方式,你能拿出你自己的完全新的公約,並使用在控制器上下文中的值來決定創建自己的視圖引擎有什麼看法。

你也許可以做這樣的事情(本書雖然可能需要調整,以滿足您的情況完全一致)

public override ViewEngineResult FindPartialView(
    ControllerContext controllerContext, 
    string partialViewName, 
    bool useCache) 
{ 
    ViewEngineResult result = null; 

    //Get the TypeName that you want to look for 
    var typeName = controllerContext.Controller.ViewData.Model.GetType().Name; 

    result = base.FindPartialView(
      controllerContext, typeName, useCache); 


    //Fall back to default search path if no other view has been selected 
    if (result == null || result.View == null) 
    { 
     result = base.FindPartialView(
      controllerContext, partialViewName, useCache); 
    } 

    return result; 
} 
相關問題