在Knockout.js模板中保留Razor语法高亮显示

时间:2012-06-27 01:16:15

标签: javascript asp.net-mvc visual-studio razor knockout.js

我的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人员如何处理这个问题。我是迂腐吗?无论如何,下一个需要选择此解决方案的开发人员可能会感谢我的关心。

5 个答案:

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

上述语法允许您将模板保存在单独的文件中。在该文件中,您将使用完整的剃刀语法突出显示(更不用说重新格式化)