web-dev-qa-db-ja.com

JavaScriptを部分ビューに入れても大丈夫ですか

メインページに2つの部分が含まれるWebアプリに取り組んでいます。常に表示される定数ブロックと、3つの部分ビューのいずれかで構成される情報ブロックです。各部分ビューはAJAXリクエストの結果として表示され、一度だけ読み込まれます(その後、jqueryによってウィンドウの切り替えが提供されます)。うまく機能しますが、1つの問題に直面しました。

部分ビューのhtmlコードには、定数ブロックと情報ブロックでも使用されるjs関数が含まれています。ページが読み込まれると、これらの関数はお互いを「見る」ことができ、動作しますが、resharperは関数宣言を見つけることができず、これについて警告します。コードにあるかみそりの構文のために、それらを外部のjsファイルに転送しても問題を解決できません。

これで何ができますか?

ありがとう。

更新:

最後に、jsコードとビューを分離する問題を解決することにしました。そのため、新しい質問は、かみそりの構文をjsファイルにどのように含めるか、または受け入れ可能な代替案は何でしたか。私が見つけた人気のあるソリューションは、グローバル変数、データ属性、そして私がもっと好きなもの、John KatsiotisのRazorJSライブラリを使用しています。

http://djsolid.net/blog/razorjs---write-razor-inside-your-javascript-files

安定して動作し、Resharperが幸せになることを願っています。

乾杯!

更新:

3年後、私はこの質問を思い出し、私の経験に応じて更新することにしました。実際、今はそのために追加のライブラリを使用することをお勧めしません。特に、あなたがプロジェクトチームの唯一のメンバーではない場合...すべてのライブラリで保証されていれば、作成者とコミュニティによってサポートされ、IDE =(たとえば、特別な構文を使用する場合)また、チームのすべての人は、それがどのように機能するかを知っている必要があります。

  1. すべてのJSを別々のファイルに保持します。できる限り隔離します。外部APIを提供します。
  2. ビューからAPI関数を呼び出します。
  3. Razorが生成したすべてのURL、テキストメッセージ、定数をリソースパラメーターとして渡します。

例えば:

jsファイル:

$.api.someInitFunction = function(resources){ ... }

見る:

<script>
    $.api.someInitFunction({
        urls: { myAction: '@Url.Action("MyAction", "MyController")' },
        messages: { error: '@errorMessage' },
        consts: { myConst: @myIntConst }
    });
</script>
59
Tomy

Resharperがあなたに警告するならば、それは大したことではありません^ _ ^

ただし、私があなたなら、JavaScriptを部分ビューにまったく入れません

部分ビューは1ページに何度も挿入される可能性があるため、JavaScriptで問題が発生します。

JavaScriptをJSファイルに分離できなかった場合は、単に別のPartialViewを作成し、これらのスクリプトをその中に入れて、メインページに表示するだけです

32
Wahid Bitar

ページに含めると機能するカプセル化された「ウィジェット」である部分ビューを作成する場合、部分ビュー内にスクリプトブロックを埋め込むと、マークアップと初期化スクリプトを部分ビューでラップすることができます。 。たとえば、サイト全体で使用する「_EventList」という名前の部分ビューがある場合があります。マスターページの2か所に配置すると、動作するはずです。ウィジェットを初期化するためにマスターページにロジックを記述する必要はありません。

1ページで2回以上使用しない場合は簡単です。ただし、必要に応じて、スクリプトをラップして、2回実行されないようにします。下記参照。スタックオーバーフロースニペットのために、コードスニペットで部分ビューを2回繰り返してマスターページに部分ビューを2回含めることでシミュレートします。

私のマスターページは次のようになります。

<div id="left-nav">
   @Html.Partial("_EventList")           
</div>

<div id="body">
</div>

<div id="right-nav">
   @Html.Partial("_EventList")
</div>

例:

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<!-- Self-contained partial view containing widget -->

<div id="widgetDiv" class="panel panel-default">

    <div class="panel-heading">Event Dates</div>
    <div class="panel panel-group">
       <ul class="widget">
         <!-- These will load dynamically -->
       </ul>
    </div>

    <script>
        $(document).ready(function() {

            // Run this once only in case widget is on page more than once
            if(typeof $widget == 'undefined') {
                $widget = $("ul.widget"); // could be more than one
                // mock data to simulate an ajax call
                var data = [
                   {Description: "March", StartDate: "03/01/2015"},
                   {Description: "April", StartDate: "04/01/2015"},
                   {Description: "May", StartDate: "05/01/2015"}
                ];

                $.each($widget, function(w, widget) {
                    // might be an $.ajax call
                    $.each(data, function(i, row) {
                        $(widget).append("<li><a href='/Widget/Search?startDate=" + row.StartDate + "'>" + row.Description + "</a></li>");
                    });
                });
            }
        });
    </script>
</div>
<!-- End of widget / partial view -->



<!-- Second copy of above for sake of example snippet -->
<!-- No need to read further -->









<!-- Self-contained partial view containing widget -->

<div id="widgetDiv" class="panel panel-default">

    <div class="panel-heading">Event Dates</div>
    <div class="panel panel-group">
       <ul class="tinylist nav nav-sidebar widget">
         <!-- These will load dynamically -->
       </ul>
    </div>

    <script>
        $(document).ready(function() {

            // Run this once only in case widget is on page more than once
            if(typeof $widget == 'undefined') {
                $widget = $("ul.widget"); // could be more than one
                // mock data to simulate an ajax call
                var data = [
                   {Description: "March", StartDate: "03/01/2015"},
                   {Description: "April", StartDate: "04/01/2015"},
                   {Description: "May", StartDate: "05/01/2015"}
                ];

                $.each($widget, function(w, widget) {
                    // might be an $.ajax call
                    $.each(data, function(i, row) {
                        $(widget).append("<li><a href='/Widget/Search?startDate=" + row.StartDate + "'>" + row.Description + "</a></li>");
                    });
                });
            }
        });
    </script>
</div>
<!-- End of widget / partial view -->
7
codenheim

私は、あなたがJavaScriptをビューに部分的にまたはその他の形で置くべきではないというWahidに同意します。私はこれを行うのに十分なコードを見てきましたが、それが役に立たないことだけを知っています。

また、Razor構文にカプセル化されたロジックをJavaScriptに転送できる必要があります。ロジックに必要な情報をJavaScriptに渡すだけです。

この次のコメントの経験から推測しているだけですが、C#またはVB.NETコードの構造を設計するのと同じ方法でJavaScriptを設計する必要があります。そうすれば、Razorを使用しているロジックはJavaScriptの一部になります。

そうすれば、JavaScriptのメンテナンスが容易になり、Resharperもより快適になります。

3
eaglestorm

これを行うと、非常に便利です。 ViewBag、HttpContextなどを使用して、部分的なJavaScriptスニペットを動的にロードするのに適しています。

その結果、T4テンプレートを使用しているような気分になります。

このようなファントムスクリプトタグを追加すると、javascript検証、インテリセンスなどを取得することもできます。

@using System.Configuration
@if (false)
{
    @:<script type="text/javascript">
}    
        $scope.clickCartItem = function(cartItem) {
            console.log(cartItem);
            window.location.href [email protected]("('" + ConfigurationManager.AppSettings["baseUrl"] + "/Checkout/' + cartItem.ItemId)");
        };
        dataAccess.getCart(
        function (response) {
            //...
        },
        function (response) {
            //...
        }
        );

@if (false)
{
    @:</script>
}
2
Bon

この質問の将来の視聴者のために、ここに私の経験があります。パーシャルでのみ使用されるスクリプトを組織のパーシャルに保持することは良い考えだと思いました。

私が抱えていた問題はデバッグ中だったので、ブレークポイントをヒットするのに苦労することがあり、スクリプトを親ビューに移動しない限り問題をトラブルシューティングできませんでした。ほとんどの場合、関数を複数回印刷するためです。セクションがこれをより良く解決し整理することを望んでいましたが、セクションは部分ビューではサポートされていません(少なくともMVC 4ではサポートされていません)。

したがって、私の答えはメンテナンスとデバッグのためであり、部分ビュー内にスクリプトを配置しないでください。

0
eaglei22