質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.53%
MVC

MVC(Model View Controller)は、オブジェクト指向プログラミングにおけるモデル・ビュー・コントローラーの総称であり、ソフトフェア開発で使われている構築パターンとしても呼ばれます。

ASP.NET

ASP.NETは動的なWebサイトやWebアプリケーション、そしてWebサービスを構築出来るようにする為、Microsoftによって開発されたウェブアプリケーション開発フレームワークです。

Q&A

解決済

3回答

27143閲覧

部分ビューでのJavaScriptを有効にする方法

lain

総合スコア161

MVC

MVC(Model View Controller)は、オブジェクト指向プログラミングにおけるモデル・ビュー・コントローラーの総称であり、ソフトフェア開発で使われている構築パターンとしても呼ばれます。

ASP.NET

ASP.NETは動的なWebサイトやWebアプリケーション、そしてWebサービスを構築出来るようにする為、Microsoftによって開発されたウェブアプリケーション開発フレームワークです。

0グッド

2クリップ

投稿2017/11/24 02:40

編集2017/11/24 06:16

###前提・実現したいこと
「ASP.NET MVC 5」での開発を最近始めたばかりです。

RenderSectionの動きがもう一つ良く分からないですが。
下記コードのように部分ビュー(_TopixView.cshtml)内でJavaScriptを書いているのですが、
部分ビュー内のJavaScriptが有効になりません。

Index.cshtml内のJavaScriptは有効になっています。

jsファイルを作成し、BundleConfig.csで追記することで動作は確認できているのですが、
部分ビュー内でしか使わないようなJavaScriptをビューの方にまとめられないかと?と思っています。

###該当のソースコード
Views/Shared/_Layout.cshtml

<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>@ViewBag.Title - マイ ASP.NET アプリケーション</title> @Styles.Render("~/Content/css") @Scripts.Render("~/bundles/modernizr") </head> <body> <div class="container body-content"> @RenderBody() </div> @Scripts.Render("~/bundles/jquery") @Scripts.Render("~/bundles/bootstrap") @RenderSection("scripts", false) </body> </html>

Views/Shared/_TopixView.cshtml

@section scripts { <script type="text/javascript"> document.getElementById("topixTitle").style.color = "red"; </script> } <h2 id="topixTitle">トピックス</h2>

Views/Home/Index.cshtml

@{ ViewBag.Title = "Home Page"; } @section scripts { <script type="text/javascript"> document.getElementById("title").style.color = "blue"; </script> } <h2 id="title">Home Index</h2> <div> @Html.Partial("_TopixView") </div>

###補足情報(言語/FW/ツール等のバージョンなど)
Windows 10
Visual Studio Professional 2017
ASP.NET MVC 5
Bootstrap 3.3.7
jQuery 3.2.1

追記-1
修正依頼を受けまして出力されたhtmlファイルを追記します。
(見やすいように改行・インデントは変更しています。)

<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Home Page - マイ ASP.NET アプリケーション</title> <link href="/Content/bootstrap.css" rel="stylesheet" /> <link href="/Content/site.css" rel="stylesheet" /> <script src="/Scripts/modernizr-2.6.2.js"></script> </head> <body> <div class="container body-content"> <h2 id="title">Home Index</h2> <div> <h2 id="topixTitle">トピックス</h2> </div> </div> <script src="/Scripts/jquery-1.10.2.js"></script> <script src="/Scripts/bootstrap.js"></script> <script src="/Scripts/respond.js"></script> <script type="text/javascript"> document.getElementById("title").style.color = "blue"; </script> </body> </html>

追記-2
部分ビューは別のページにも配置されるので、
@Html.Partal("_TopixView")の次の行に@section scriptsを書く案は、現実的ではないですね。
いちおう試してみたのですが@section scriptsの分割して書くと
「HttpException」が吐かれるので、一カ所にまとめないと駄目でした。
セクション名を変えれば大丈夫でしたが。

外部ファイルにする案は、
topix.js

JavaScript

1document.getElementById("topixTitle").style.color = "red";

_TopixView.cshtml

<h2 id="topixTitle">トピックス</h2> <script type="text/javascript" src="~/Scripts/topix.js"></script>

上記のようにすると反映されるようになりました。

ただ、sk_3122様が書かれているのですが、投稿したコードのように単純なものではなく
実際のコードはAjaxでJSONデータ受け取ってDOMでゴニャゴニャするつもりなので、
どうなるかを試してみたいと思います。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2017/11/24 03:15 編集

html ソースを見て、_Layout.cshtml の @RenderSection("scripts", false) の位置にレンダリングされるスクリプトはどうなってますか? Index.cshtml の @section scripts の { } 内のスクリプトは出力されるが、_TopixView.cshtml の方の @section scripts の { } 内のスクリプトは出力されないということですか?
lain

2017/11/24 03:36

SurferOnWww様 出力されたhtmlを追記しました。おっしゃられてる通り、_TopixView.cshtemの@section scriptの内容が出力されていない状態です。
退会済みユーザー

退会済みユーザー

2017/11/24 03:44

ということは、Index.cshtml の @Html.Partial("_TopixView") の次に行あたりに @section scripts { ... } として _TopixView.cshtml 用のスクリプトを記述する他なさそうな気がしますが、それでは目的に叶わないのですよね・・・
退会済みユーザー

退会済みユーザー

2017/11/24 05:43 編集

あとは、取り込むスクリプトは外部ファイルと理解してますが、あらかじめ minify しておいて、部分ビューのコード内にそれへの参照(script タグ)を埋め込みと言う方法もありそうです。バンドル機能はどのみち使えないので、機能的にはそれで良さそうに思いますが、いかがですか?
lain

2017/11/24 06:18

SurferOnWww様 ご返答ありがとうございます。ここでは書きにくいので追記-2をしました。
退会済みユーザー

退会済みユーザー

2017/11/24 06:56 編集

> 実際のコードはAjaxでJSONデータ受け取ってDOMでゴニャゴニャするつもりなので ← ということは、jQuery.js より後で読み込まれなければダメということでしょうか? であれば、ちょっと安易な方法のような気もしますが defer 属性を付けると言う手がありそうです。<script> タグに async / defer を付けた場合のタイミング https://qiita.com/phanect/items/82c85ea4b8f9c373d684 後は、サーバー側のコードで script タグを位置指定して書き込むという方法ぐらいでしょうか。(Web Forms アプリではよく使う手なのですが、MVC では未検討なので、できなかったらすみません)
lain

2017/11/24 08:35

deferを使用する方法を試してみました。jQueryを使用したコードでも動作しました。これは良く使われる方法なのですか?(初めて見た気がするので...)
退会済みユーザー

退会済みユーザー

2017/11/24 08:44

defer はもともとは IE 専用だったようですが、最近は他のメジャーなブラウザでも使えるようです。
lain

2017/11/27 00:46

deferを使用したコードで、いま確認できる環境、Windows/IE11/Edge/Chrome、android/Chrome、iPhone/Chrome/Safariでの(それぞれ最新バージョン)動作は確認できました。どこまで古いOS・ブラウザに対応させるかは別途検討するとして、有益な情報ありがとうございました。
guest

回答3

0

ベストアンサー

(コメント欄にもコードが書けると良いのですけど…)

「jsを読み込んでから<body>内を読みにいくから表示が遅くなる」というのを、
どこかで書かれていたのと、
VSが作成するテンプレートも下に書かれているので、最近はそういうものだという認識でいたのですが。

正直 まんま同じです…
自動生成されたコードがこうなっているからとりあえずこの並びにしておこう、的な…

まあVSの自動生成コードじゃない、一般的な html では
jquery の読み込みを <head> に書いてるケースとかも見るので、
head に持ってって駄目なことはないのではないかと思うのですが…


一応参考までに、
私が実装した際は、部分ビューで使用する外部ファイルの読み込みは
Index.cshtml の @section Scripts {} に書きました。
これなら jquery の後にレンダリングされるので。

もう 「部分Viewの読み込み」 + 「部分View用の外部ファイルの読み込み」 はワンセット、と割り切りました。
(js + css でワンセット、みたいなライブラリもあるし、同じような感じで もうルール化してしまえばそれはそれで良いかなと)

特定の部分View用に読み込む外部ファイルには、一応コメントを付けて後で分かるようにだけしておきました。

Index.cshtml

@section scripts { <script type="text/javascript" src="../js/my-calendar.js"></script> <script type="text/javascript" src="../js/hoge-edit.js"></script> <!-- Hoge001用 --> <script type="text/javascript" src="../js/hoge001.js"></script> <!-- Hoge001用 --> <script> ... </script> } ... @Html.Partial("_Hoge001")

投稿2017/11/24 09:13

sk_3122

総合スコア1126

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2017/11/24 09:36

できるだけ、一人の回答者は一つの回答欄を使っていただけないでしょうか(それがTeratail の流儀のようですので)。Teratail は know-how の蓄積も目的としているとのことで、後から検索などでここにたどり着いた人にも読みやすくなるような配慮をいただけると幸いです。
sk_3122

2017/11/24 09:45

すみません、そう思ったのですが コメント欄だとコードが書けなくて・・・ と思ったのですが、回答欄に追記で書けば良かったですね。(今気が付きました) すみません、今度から追記で書くようにします。
lain

2017/11/27 01:09

もともとの疑問であった 「@RenderSection()」「@section sectionName{}」のセットが部分ビューで使用できない事が分かりました。 そのうえで、どうすれば良いかのご提案いただき、ありがとうございます。 部分ビューに対応するJavaScriptファイルを作成して、下記の2パターンで実現できました。 1、部分ビューの中でdeferを使用し定義する。 2、部分ビューを埋め込むcshtmlの@sectionの中で定義する。 どちらが良いかは好みの問題になるかと思うので、どうするかはこれから考えてみます。 ベストアンサーはこちらのほうにしか付けられないので、こちらに付けましたが、 SurferOnWww様、sk_3122様ありがとうございました。
guest

0

ちょっとコードが書きたかったのでこっちに書きます。
読み込まれる順番は以下のようになっていると認識しています。

部分View に 「jquery を使用しているスクリプトファイルの読み込み」 を
そのまま書いちゃうと多分まずかろうと思うのは、
@RenderBody() が @Scripts.Render("~/bundles/jquery") よりも前にあるからです。

<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>@ViewBag.Title - マイ ASP.NET アプリケーション</title> @Styles.Render("~/Content/css") @* ★BundleConfig.cs で new StyleBundle("~/Content/css") に指定されているものはここにレンダリングされる *@ @Scripts.Render("~/bundles/modernizr") </head> <body> <div class="container body-content"> @* ★Index.cshtml の内容はここにレンダリングされる、なので部分Viewに書いた内容もここにレンダリングされる *@ @RenderBody() </div> @Scripts.Render("~/bundles/jquery") @* ★jquery のjsはここで読み込まれる *@ @Scripts.Render("~/bundles/bootstrap") @* ★bootstrap のjsはここで読み込まれる *@ @RenderSection("scripts", false) @* ★section Scripts {} に書かれたものはここにレンダリングされる *@ </body> </html>

@Scripts.Render() 達を <body> の前に持ってっちゃっても良いものなのかどうかはちょっとわからないです
(´□`)???

投稿2017/11/24 06:46

sk_3122

総合スコア1126

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

lain

2017/11/24 08:26

こういう風に書いていただくと、理解しやすいです。 部分ビューの中にjsを書いて、下の@Script.Render達を<head>内に置いて実行すると、 確かに動作はします。 最後に書かれているように、jsを前に持っていくのはどうなんでしょうか? 「jsを読み込んでから<body>内を読みにいくから表示が遅くなる」というのを、 どこかで書かれていたのと、 VSが作成するテンプレートも下に書かれているので、最近はそういうものだという認識でいたのですが。 そういえば、昔は<head>内に書かれていたような... stackoverflowで今回の質問と同じ内容(MVC3ですが)を見つけたので読んでいたのですが、 部分ビューにJS書くのは駄目とか書いてあったりして(英語苦手なので間違えてるかもしれませんが)、 今回の質問の根底部分が揺らいできています。 https://stackoverflow.com/questions/7556400/injecting-content-into-specific-sections-from-a-partial-view-asp-net-mvc-3-with
guest

0

私も色々調べながら実装しているので全く詳しくはないのですが…
部分Viewは何回も読み込まれるケースを想定しているので、部分View内で @section は使えないよ!ということみたいですね。

でも一回しか読み込まないし、その部分Viewでしか使わないjsをまとめたいよ!と私も思ったので、
私は以下のようにしてみたのですが… どうなんでしょうね。 私も正解が知りたいです・・・


_Hoge001.cshtml (部分View)

... <script> var Hoge001Js = { // 初期処理 init: function() { var self = this; // btn-hello クリック時の処理 $("#btn-hello").on("click", function() { self.sayHello("Yamada"); }); // btn-seeyou クリック時の処理 $("#btn-seeyou").on("click", function() { self.saySeeyou("Suzuki"); }); }, // 関数 sayHello: function(name) { alert("Hello, " + name); }, // 関数 saySeeyou: function(name) { alert("See you " + name); } }; </script>

Index.cshtml

... @section Scripts { <script> $(function() { if (window.Hoge001Js) { Hoge001Js.init(); } }); </script> }

部分Viewでは Hoge001Js の定義だけする。
Index で、Hoge001Js が定義されていたら Hoge001Js.init() を呼ぶ、的な

投稿2017/11/24 03:45

編集2017/11/24 07:14
sk_3122

総合スコア1126

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2017/11/24 04:50

外部スクリプトファイルの場合はどのようになりますか?
sk_3122

2017/11/24 05:14 編集

部分View固有のスクリプトを外部ファイルに書いた場合、ということでしょうか。 その場合は Index.cshtml の @section scripts に外部ファイルの読み込みを記述する感じになるかなあと思います。 ----- @section scripts { <script type="text/javascript" src="../js/hoge001.js"></script> <script> ... </script> } ----- ==================== ↓ _Layout.cshtml の記述 ---- @Scripts.Render("~/bundles/jquery") @Scripts.Render("~/bundles/bootstrap") @RenderSection("scripts", false) ---- 上のような感じになってる場合、 @section scripts {} 内に書かれたものは jquery の後にレンダリングされるのですが、 多分 部分View内に外部ファイルの読み込みを書くと、jquery の読み込みよりも先に読まれると思います。 jquery 等を使用していない、標準javascriptのみで書かれたものなら部分View内で読み込んでしまってもよさそうな気はします。 (試してませんが)
lain

2017/11/24 06:23

追記-2の方に外部スクリプトを使用する場合を試してみました。 今回質問のような単純なJavaScriptの場合はうまくいきました。 実際はjQueryを使ったりするつもりなので、使ったのを試してみたいと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.53%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問