2011-02-04 8 views
6

Ben (yani çalışmıyor) aşağıdaki bir Page.cshtml benzer vardır:Asp.net mvc Razor ViewEngine ile isteğe bağlı bir seçenek oluşturmanın bir yolu var mı?

@{ 
    Layout = "../Shared/Layouts/_Layout.cshtml"; 
    var mycollection = (ViewBag.TheCollection as IQueryable<MyCollectionType>); 
} 

<h2>@ViewBag.Title</h2> 

content here 

@if (mycollection != null && mycollection.Count() > 0) 
{  
    @section ContentRight 
    {  
     <h2> 
      Stuff 
     </h2> 
     <ul class="stuff"> 
      @foreach (MyCollectionType item in mycollection) 
      { 
       <li class="stuff-item">@item.Name</li> 
      } 
     </ul> 
    } 
} 

Dediğim gibi, bu işe yaramaz. Koleksiyonda hiçbir şey yoksa bölümü tanımlamak istiyorum. Bu çalışma gibi bir şeyin olması için herhangi bir yolu var mı? Yoksa, diğer seçeneklerim nelerdir? Bu Razor ViewEngine için çok yeni. Benim düzende

Düzenleme

i vardır: bölüm boşken

@if(IsSectionDefined("ContentRight")) 
{ 
    <div class="right"> 
     RenderSection("ContentRight") 
    </div> 
} 

ne ben istemiyorum çıkışına div olduğunu.

cevap

3

Onu nasıl çalıştırdığımı öğrenmek için. sayfamda

i var:

@{ 
    Layout = "../Shared/Layouts/_Layout.cshtml"; 
    var mycollection = (ViewBag.TheCollection as IQueryable<MyCollectionType>); 
    ViewBag.ShowContentRight = mycollection != null && mycollection.Count() > 0; 
} 

sonra benim düzeninde i vardır: bölüm tanımlanır

@if(IsSectionDefined("ContentRight") && (ViewBag.ShowContentRight == null ||ViewBag.ShowContentRight == true)) 
{ 
    <div class="right"> 
     RenderSection("ContentRight") 
    </div> 
} 
else if(IsSectionDefined("ContentRight")) 
{ 
    RenderSection("ContentRight") 
} 

Eğer işlenecek vardır, ama ben istemiyorum hiçbir içerik varsa Eğer bilmek istediğim daha iyi bir yol varsa s

.

+0

Maalesef şu anda muhtemelen en iyi seçeneğiniz bu. Başka bir olası seçenek, "@section" in aşağıya çevrildiği "DefineSection" u çağırmak ve doğrudan çağırmaktır. Sorun, Markör'ü Razor v2'de (geleceğe baktığımız bir şey) bir lambdaya koyamazsınız, böylece içeriğinizi bir @helper yapısında tanımlamanız ve bu yardımcıyı DefineSection lambda'dan çağırmanız gerekir. . Sonunda, sahip olduğunuz gibi bunu yapmak daha kolay olabilir. Ama bunu gelecekteki sürümlerde geliştirmeye bakacağız! –

-1

Sen IsSectionDefined

Layout.cshtml ile eğer açıklamada senin tüm bölüm sarabilirsiniz:

@if (IsSectionDefined("ContentRight")) 
{ 
    <div> 
    @RenderSection(name: "ContentRight", required: false) 
    </div> 
} 

Sizin cshtml sayfa: Biraz hacky bir şey yapıyor sona erdi

@section ContentRight 
{  
    @if (mycollection != null && mycollection.Count() > 0) 
    { 
    <h2> 
     Stuff 
    </h2> 
    <ul class="stuff"> 
     @foreach (MyCollectionType item in mycollection) 
     { 
      <li class="stuff-item">@item.Name</li> 
     } 
    </ul> 
    } 
} 
+0

i anda ne olduğunu gerekli = false – ajma

+0

ile rendersection Düzeni dosyasında IsSectionDefined koymak ve aramak istediğiniz, ama bu bölümün çıktısı çünkü bölümün içinde hiçbir şey olmasa bile tanımlanır. –

+0

Ya etrafındaki divlar IsSectionDefined ile sarılırsa? – ajma

2

İşleyici, düzen dosyasında bir şekilde çağrılacak yöntemi beklemektedir. Oluşturucuyu dondurabilir ve "global" şartlarını (oturum açma düşüncesini) kullanabilirsiniz. perf için özel statik salt okunur alan bilgi ile

@{ 
    ViewBag.content = RenderBody(); 
} 
@if (Request.IsAuthenticated) { 
     @ViewBag.content; 
} 
else { 
     @Html.Partial("_LoginPartial") 
} 
0

Uzatma yöntemi: cshtml olarak

private static readonly FieldInfo RenderedSectionsFieldInfo = typeof(WebPageBase).GetField("_renderedSections", BindingFlags.Instance | BindingFlags.NonPublic); 

public static void EnsureSectionsAreRegisteredAsRendered(this WebPageBase webPageBase, params string[] sectionNames) 
{ 
    var renderedSections = RenderedSectionsFieldInfo.GetValue(webPageBase) as HashSet<string>; 
    if (renderedSections == null) 
    { 
     throw new WebCoreException("Could not get hashset from private field _renderedSections from WebPageBase");  
    } 
    foreach (var sectionName in sectionNames) 
    { 
     if (!renderedSections.Contains(sectionName)) 
     { 
      renderedSections.Add(sectionName); 
     } 
    } 
} 

:

@{ this.EnsureSectionsAreRegisteredAsRendered("SectionName1", " SectionName2", "…"); } 

Evet, evet, evet .... Biliyorum ... Kötü yansıma! Eğer bir görünüm temel sınıf yoksa

public HelperResult RenderSection(string name, Func<dynamic, HelperResult> defaultContents) 
{ 
    if (IsSectionDefined(name)) 
    { 
     return RenderSection(name); 
    } 
    return defaultContents(null); 
} 

, ben tavsiye: Kendi risk :) benim bakış taban sınıfında aşağıdaki yöntemi kullanın

0

(bu mükemmel blog yazısı http://haacked.com/archive/2011/03/05/defining-default-content-for-a-razor-layout-section.aspx/) Kullanmanızdan Birincisi, görünümlerinize her çeşit küçük ekstra işlevsellik eklemenizi sağlar.Sadece şu imzası ile bir sınıf oluşturmak: public abstract class MyViewPage<T> : WebViewPage<T> ve sonra bunu ayarlamak senin web.config:

<system.web.webPages.razor> 
    <pages pageBaseType="MyViewPage"> 
    ... 
    </pages> 
</system.web.webPages.razor>