1

私のWebアプリケーションは、RazorとKnockout.jsを使用したASP.NETMVC4です。ビューモデルの階層はかなり深く複雑になり、HTMLのモノリシックスラブではなく、対応するビューにネストされたノックアウトテンプレート(それぞれに子テンプレートのfor / eachを含む)を使用する方向に進んでいます。

私を悩ませているのは<script type="text/html" id="scary-template">、コンテンツのKnockoutテンプレート定義構文を使用すると、スクリプトとして解釈されるため、VisualStudioでのRazor構文の強調表示が失われることです。テンプレートは十分に複雑で、テキストもすべて真っ黒になっています。

私が検討したいくつかのアプローチは、Html.Rawを使用して開始および終了スクリプトタグを出力するか、Html.BeginKOTemplate(id)のようなHtmlHelper拡張機能を使用することです。

他のASP.NETMVCの人々がこれにどのように取り組んでいるかを知りたいです。私は衒学者ですか?いずれにせよ、このソリューションを採用する必要がある次の開発者は、おそらく私に気を配ってくれてありがとう。

4

5 に答える 5

5

Visual Studioは使用していませんが、役立つ提案がいくつかあります。

Knockout 2.1以降では、textareaタグを使用してテンプレートを定義できます。これにより、多くのエディター(phpDesignerとNotepad ++の2つを含む)で構文の強調表示がサポートされます。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 ここを参照)。display:noneもちろん、スタイル はまだ必要です。

<div style="display:none" data-bind="allowBindings:false">
    <div id="mytemplate">
        <div>template content</div>
    </div>
</div>
于 2012-06-27T01:56:46.050 に答える
1

IDisposableを実装するKnockoutTemplateクラスを返すHtmlHelper拡張機能を作成しました。

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を使用すると、テンプレート自体のマークアップがブラウザーによってテンプレートインスタンスとして解釈されるという考えが気に入らなかったため、今のところスクリプトブロックアプローチに固執していますが、少なくとも必要に応じて、後ですべてのインスタンスを1か所で変更します。

于 2012-06-27T03:20:53.820 に答える
1

個人的には、ノックアウト外部テンプレートエンジンを使用して、他のファイルから動的にテンプレートをロードします。これには独自の長所と短所がありますが、優れた副作用として、テンプレートを.htmlファイルに保存でき、ラップする必要がまったくなく、すべての構文の強調表示が保持されます。スクリプトタグのIDを使用するだけでなく、外部テンプレートエンジンは、テンプレート名(mytemplate.htmlなど)で指定したディレクトリ内のファイルも検索します。

私の経験では、これはプロジェクトをより組織化する傾向があり、プロジェクト間のコードの再利用を促進するのに役立ちます。唯一の欠点は、より多くのファイルをダウンロードすることによる遅延の追加です。これは、必要なときにのみテンプレートをロードするため(同じテンプレートに対して複数のリクエストを行わないため)、遅延ロードによって実際にパフォーマンスが向上する可能性があります。

于 2012-06-27T13:12:44.577 に答える
0

簡単な提案です。ここで説明したように、JavaScriptとRazorを分けてください:https ://stackoverflow.com/a/11109799/538387

于 2012-06-27T03:24:50.323 に答える
0

この問題を解決するには、Razorsの部分ビューを使用します。

<script type="text/html" id="launchTemplate">
   @Html.Partial("Templates/_LaunchView", null)
</script>

上記の構文を使用すると、テンプレートを別のファイルに保存できます。そのファイルには、完全なかみそり構文の強調表示があります(再フォーマットは言うまでもありません)

于 2012-09-21T00:00:36.273 に答える