Что эквивалентно ColdFusion Model Glue для @s ection в ASP.NET MVC 3?

В ASP.NET MVC 3 вы можете иметь @section в представлении:

@section SideBar {
    <p>Some content</p>
    <p>Some more content</p>
}

<p>Body content</p>

Затем в главном представлении вы должны использовать это для рендеринга:

<div id="sidebar">
    @RenderSection("SideBar", false)
</div>

@RenderBody()

Что будет эквивалентом ColdFusion в среде Model Glue? Я знаю, что могу установить простые переменные в представлении:

<cfset event.setValue("section", "Tables")>

Затем используйте их в мастер-шаблоне так:

<cfif event.exists("section")><h3>#event.getValue("section")#</h3></cfif>

Но это работает только для однострочников и простых строк. То, что я хотел бы сделать, это включить весь блок HTML. Каков наилучший способ сделать это? Я думаю, что это будет работать в теории:

<cfsavecontent variable="sidebar">
    <p>Some content</p>
    <p>Some more content</p>
</cfsavecontent>

<cfset event.setValue("sidebar", sidebar)>

Но мне было интересно, есть ли лучший способ сделать это.

Редактировать:

В ответ на ответ Адама Кэмерона Model Glue, насколько я могу судить, поддерживает только возможность объединения отдельных файлов в один шаблон:

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>

Мне нужно иметь возможность объявить содержимое боковой панели в page.cfm Посмотреть. Мысль здесь в том, что где-то в главном шаблоне будет div, который позволяет использовать небольшой фрагмент HTML, скажем, изображение с текстовым описанием и ссылкой, которую может заполнить любой вид. Не было бы смысла иметь что-то вроде Page1.cfm а также Page1SidebarContent.cfm, Page2.cfm а также Page2SidebarContent.cfm, так далее...

4 ответа

Решение

ModelGlue не поддерживает то, что вы хотите сделать из коробки. Однако этого достаточно легко достичь, используя предложение Питера и помощников ModelGlue для инкапсуляции.

Создайте новый cfc, назовите его PageFragment.cfc и поместите в свой каталог помощников ModelGlue.

// 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;
 }
}

Тогда в ваших взглядах вы можете сделать

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>

Чтобы избежать необходимости сохранять все ваши фрагменты, вы можете создать тег, который использует thistag.generatedcontent и область вызова для доступа к вашим помощникам.

Используя помощники для инкапсуляции функциональности, ее действительно легко использовать повторно или изменить позже, не изменяя свои представления, например, вы можете захотеть добавить кеширование.

(К сожалению) Я не касался MG целую вечность, но я просто погуглил документы, как напоминание.

Вы должны прочитать о том, как работают представления, но эта страница документов кратко описывает это:

http://docs.model-glue.com/wiki/ReferenceMaterials/ViewApi

Конкретно этот фрагмент кода:

<cfoutput>#viewcollection.getView("body")#</cfoutput> 

Вероятно, это случай, когда вы немного прочтете документы и напомните себе о том, как работает реализация MVC в модели glue (в частности, в части V, в вашем случае!).

Теперь я понимаю, что вы имеете в виду. Я не уверен, что MG будет иметь такую ​​встроенную функциональность, потому что в среде MVC не совсем то, что нужно делать подобные вещи: вы как бы соединяете контроллер и модель вместе в файле представления, Возможно, для этого есть веская причина, но мне интересно, может быть, именно ваш подход может привести к тому, что вы здесь погубите? Разве вы не можете поместить элемент "получить боковую панель" в контроллер и сделать так, чтобы он вызывал модель, и добавить вид боковой панели, если это необходимо? Вот как бы я подошел к этому.

Тем не менее, я знаю, что бесполезно, когда люди говорят: "Я не собираюсь отвечать на ваш вопрос, я просто собираюсь пожаловаться на него", поэтому я посмотрю вокруг и посмотрю, смогу ли я придумать что-то.

Однако, учитывая, что вы хотите использовать здесь подход MVC, возможно, не пытайтесь заставить MG сделать это за вас, просто сделайте то, что предлагает Питер, и запишите переменную в представлении page.cfm, вставьте ее в разумно структурированная структура (хорошая тавтология, Кэмерон), а затем ищите ее в представлении, которое вы хотите визуализировать.

Я не использовал Model-Glue и ASP.NET MVC, но кажется, что вы можете достичь следующим образом:

В page.cfm делаем:

<cfsavecontent variable="Request.SubContent['ThisPage'].Sidebar">
    <p>Some content</p>
    <p>Some more content</p>
</cfsavecontent>

<p>Body content</p>

Затем в main.cfm используйте:

<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>

В зависимости от того, как все устроено, вы можете предпочесть кешировать контент в постоянной области и / или скрыть его за парой методов (возможно, даже расширением Model-Glue, чтобы разрешить это изначально; в конце концов, это Open Source), но, надеюсь, это дает общее представление?

Другие вопросы по тегам