我的Web应用程序是带有Razor和Knockout.js的ASP.NET MVC4。视图模型层次结构变得相当深刻和复杂,我更倾向于使用嵌套的Knockout模板用于相应的视图(每个模板都有for / each用于其子模板等),而不是单片的HTML。
令我恼火的是,当使用<script type="text/html" id="scary-template">
的Knockout模板定义语法时,内容在Visual Studio中失去了Razor语法高亮,因为它被解释为脚本。模板很复杂,文本也都不是纯黑色。
我考虑过的一些方法是使用Html.Raw输出开始和结束脚本标签,或HtmlHelper扩展名,如Html.BeginKOTemplate(id)。
我很想知道其他ASP.NET MVC人员如何处理这个问题。我是迂腐吗?无论如何,下一个需要选择此解决方案的开发人员可能会感谢我的关心。
答案 0 :(得分:5)
我不使用Visual Studio,但我有一些可能适合您的建议。
从Knockout 2.1开始,您可以使用textarea
标签定义模板,该标签将支持许多编辑器中的语法突出显示(包括我使用的两个,phpDesigner和Notepad ++)。要确保textarea
实际上不显示在页面上,它必须具有display:none
样式(或者位于具有该样式的容器中)。
<textarea id="mytemplate" style="display:none">
<div>template content</div>
</textarea>
或
<div style="display:none">
<textarea id="mytemplate">
<div>template content</div>
</textarea>
</div>
您还可以使用div
等任何标记来定义模板。但这增加了一些开销。首先,浏览器将解析(并可能修改)模板内容。其次,除非你另外指示,否则它将被Knockout解析。您可以通过将容器节点传递给不包含模板节点的applyBindings
,或者通过创建绕过模板绑定的自定义绑定来执行此操作(请参阅allowBindings
here)。当然,你仍然需要display:none
风格。
<div style="display:none" data-bind="allowBindings:false">
<div id="mytemplate">
<div>template content</div>
</div>
</div>
答案 1 :(得分:1)
我已经创建了一个HtmlHelper扩展,它返回一个实现IDisposable的KnockoutTemplate类:
public static KnockoutTemplate KnockoutTemplate(this HtmlHelper htmlHelper, string templateID)
{
return new KnockoutTemplate(templateID, htmlHelper.ViewContext.Writer);
}
public class KnockoutTemplate: IDisposable
{
private TextWriter _textWriter;
private bool _disposed;
public KnockoutTemplate(string templateID, TextWriter textWriter)
{
_textWriter = textWriter;
_textWriter.WriteLine(String.Format("<script type=\"text/html\" id=\"{0}\">", templateID));
}
public void EndTemplate()
{
Dispose(true);
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (!_disposed)
{
_disposed = true;
_textWriter.WriteLine("</script>");
}
}
}
像这样使用:
@using (Html.KnockoutTemplate("sum-assured-template"))
{
<div>Template markup...</div>
}
进一步的想法我不喜欢这样的想法:使用div,模板本身的标记会被浏览器解释为模板实例,所以我现在一直坚持使用脚本块方法,但是至少我可以在以后的某个地方更改所有实例。
答案 2 :(得分:1)
就个人而言,我使用knockout external template engine从其他文件动态加载模板。这有其自身的优点和缺点,但一个很好的副作用是模板可以存储在.html文件中,根本不需要包装 - 保留所有语法高亮。外部模板引擎不是仅使用脚本标记的id,而是在模板名称(例如mytemplate.html)的任何目录中查找文件。
根据我的经验,这也有助于使项目更有条理,并有助于促进项目之间的代码重用。唯一的缺点是下载更多文件会增加延迟 - 这实际上可以通过延迟加载来提高性能,因为它只会在需要时加载模板(并且不会对同一模板发出多个请求)
答案 3 :(得分:0)
只是一个快速的建议,像我在这里描述的那样单独的JavaScript和Razor:https://stackoverflow.com/a/11109799/538387
答案 4 :(得分:0)
使用Razors部分视图来克服此问题。
<script type="text/html" id="launchTemplate">
@Html.Partial("Templates/_LaunchView", null)
</script>
上述语法允许您将模板保存在单独的文件中。在该文件中,您将使用完整的剃刀语法突出显示(更不用说重新格式化)