我是一個較新的Web開發人員(約1年的經驗),他剛剛加入了一家新公司,該公司使用Umbraco CMS開發了許多我們開發的網站。在我上一份工作中,我只接觸了WebForms,所以在開始這項工作之前我做了一點關於MVC的研究,並且做了一個初學者的教程,但我不確定當涉及到的時候我是否理解社區的「最佳實踐」這個東西,所以希望你們可以幫助我。在Umbraco CMS中,有一些名爲「Macro-Scripts」的組件,它基本上是一個Razor View(.CSHTML),它允許您在頁面中編寫一堆C#& HTML,並在其上顯示此「Macro-Script」您選擇的任何CMS頁面。在我的教程中(我在2個月前完成了這個教程),我想我記得讀過一些關於從不將條件邏輯/ C#與HTML混合在一起的東西,並且最好使用Models &控制器?我有點困惑,因爲我們並不真正爲我們的網站建立控制器,因爲它們是CMS頁面,如果它們需要除Rich-Text以外的任何內容,那麼我們只需創建一個「Macro-Script」並放置它在需要擴展功能的頁面上。如何做「適當」的MVC?
我在這裏工作的第一個月裏發現的是,如果我能夠讓我的代碼在整個網站上可重複使用,那麼我可以節省大量時間,但我並不確定該怎麼做以「MVC友好」的方式?下面是一個「宏腳本」示例,它顯示了在CMS中創建的表單,然後嘗試獲取公司「聯繫人」信息並將其顯示在表單下。我附加的例子非常簡單,但是我所見過的一些宏腳本變成了超過500行的巨大混亂,每個循環,開關和代碼塊都不可讀。
是否有可能將這種類型的代碼拆分成模型以便在此視圖中使用?分割代碼有沒有什麼好處,而不是把它們放在同一個視圖中? (如果有足夠的好處,我想向我的同事介紹這一點,並更改編碼標準)。有人能給我一個例子,說明如果將它分解成適當的「MVC」,這將如何看待?如果這不是發佈此類問題的正確位置,請將我指向更好的StackExchange站點。謝謝。
宏腳本搶CMS表&公司信息
@inherits umbraco.MacroEngines.DynamicNodeContext
@*
Model = The current page the macro is executed on
@Model.bodyText
Parameter = collection of parameter values passed from the macro
@Paramter.myParam
Library = utillity library with common methods
@Library.NodeById(1233)
*@
@* The fun starts here *@
@{
string formClass = "form-content";
var configNode = Model.AncestorOrSelf().Descendants("ConfigurationContainer").FirstOrDefault();
if (configNode != null && configNode.Id > 0)
{
formClass = "form-content show-address";
}
if (custom.Library.NodeHasPropertyAndValue(Model, "bodyText"))
{
<hr />
}
<div class="form-page contact-us">
<div>
<div class="@formClass">
@Html.Raw(umbraco.library.RenderMacroContent("<?UMBRACO_MACRO macroAlias=\"umbracoContour.RazorRenderForm\" formGuid=\""+Model.selectedForm+"\" ></?UMBRACO_MACRO>", Model.Id))
</div>
@if (configNode != null && configNode.Id > 0)
{
<address class="address-content">
@if (custom.Library.NodeHasPropertyAndValue(configNode, "officeAddress"))
{
var addressDisplay = (custom.Library.NodeHasPropertyAndValue(configNode, "officeAddress2")) ? string.Format("{0}, {1}", configNode.officeAddress, configNode.officeAddress2) : configNode.officeAddress;
string locationString = string.Empty;
string cityDisplay = (custom.Library.NodeHasPropertyAndValue(configNode, "officeCity")) ? configNode.officeCity : string.Empty,
stateDisplay = (custom.Library.NodeHasPropertyAndValue(configNode, "officeState")) ? configNode.officeState : string.Empty,
zipDisplay = (custom.Library.NodeHasPropertyAndValue(configNode, "officeZip")) ? configNode.officeZip : string.Empty;
if (!string.IsNullOrEmpty(cityDisplay) && !string.IsNullOrEmpty(stateDisplay))
{
locationString = string.Format("<br />{0}, {1} {2}", cityDisplay, stateDisplay, zipDisplay);
}
@[email protected](locationString)
}
@if (custom.Library.NodeHasPropertyAndValue(configNode, "officePhone"))
{
<br /><i class="fa fa-phone"></i> @configNode.officePhone
}
@if (custom.Library.NodeHasPropertyAndValue(configNode, "officeFax"))
{
<br /><i class="fa fa-fax"></i> @configNode.officeFax
}
@if (custom.Library.NodeHasPropertyAndValue(configNode, "officeEmail"))
{
<br /><i class="fa fa-envelope"></i> <a href="mailto:@configNode.officeEmail">@configNode.officeEmail</a>
}
</address>
}
</div>
</div>
if (custom.Library.NodeHasPropertyAndValue(Model, "lowerText"))
{
@Html.Raw(Model.lowerText)
}
}
儘管我很難說出原因,但您已經清楚地考慮了這個問題,它太寬泛了。你基本上要求如何做MVC的騙子。 :(我要說的一件事就是基本邏輯應該在你的'.chtml'視圖中,你應該傳遞和已經被處理的對象,它包含了顯示頁面所需的最小值,它不需要進一步處理。而不是基本的循環(比如foreach循環),任何處理都應該在你的控制器中傳遞給視圖之前完成,我希望這有助於你的工作:) – Luke
CodeReview可能是一個很好的SE站點,你的代碼正在工作,你只是尋找反饋和(可能)更好的方法 –
由於這個問題特別與Umbraco相關,Umbraco在一定程度上具有MVC的「風味」,所以問題並不像它最初出現的那樣廣泛 - 請參閱以下關於方式的答案清理這些等等。似乎你需要回顧一下http://our.umbraco.org上的Umbraco實現文檔 –