web-dev-qa-db-ja.com

JavascriptからMVCのモデルプロパティにアクセスする

私のビューモデルにラップされている次のモデルがあります

public class FloorPlanSettingsModel
{
    public int Id { get; set; }
    public int? MainFloorPlanId { get; set; }
    public string ImageDirectory { get; set; }
    public string ThumbnailDirectory { get; set; }
    public string IconsDirectory { get; set; }
}

Javascriptから上記のプロパティの1つにアクセスするにはどうすればいいですか?

私はこれを試したが、私は "未定義"になった

var floorplanSettings = "@Model.FloorPlanSettings";
alert(floorplanSettings.IconsDirectory);
128
Null Reference

次のようにして、サーバーサイドモデル全体を取り、それをJavascriptオブジェクトに変えることができます。

var model = @Html.Raw(Json.Encode(Model));

あなたの場合は、FloorPlanSettingsオブジェクトが欲しいだけなら、そのプロパティをEncodeメソッドに渡してください。

var floorplanSettings = @Html.Raw(Json.Encode(Model.FloorPlanSettings));
198

答えの内容

1).cshtmlファイル内のJavascript/Jqueryコードブロック内のモデルデータにアクセスする方法

2).jsファイルのJavascript/Jqueryコードブロック内のモデルデータにアクセスする方法

.cshtmlファイルのJavascript/Jqueryコードブロック内のModelデータにアクセスする方法

JavaScript変数へのc#変数(Model)の割り当てには2種類あります。

  1. プロパティ割り当て - intstringDateTimeなどの基本データ型(例:Model.Name
  2. オブジェクト割り当て - カスタムクラスまたは作り付けクラス(例:ModelModel.UserSettingsObj

これら2つの割り当ての詳細を調べてみましょう。

答えの残りの部分については、例として以下のAppUserモデルを考えてみましょう。

public class AppUser
{
    public string Name { get; set; }
    public bool IsAuthenticated { get; set; }
    public DateTime LoginDateTime { get; set; }
    public int Age { get; set; }
    public string UserIconHTML { get; set; }
}

そしてこのモデルに割り当てる値は

AppUser appUser = new AppUser
{
    Name = "Raj",
    IsAuthenticated = true,
    LoginDateTime = DateTime.Now,
    Age = 26,
    UserIconHTML = "<i class='fa fa-users'></i>"
};

プロパティ割り当て

代入に異なる構文を使用して結果を観察しましょう。

1)プロパティの割り当てを引用符で囲まないでください。

var Name = @Model.Name;  
var Age = @Model.Age;
var LoginTime = @Model.LoginDateTime; 
var IsAuthenticated = @Model.IsAuthenticated;   
var IconHtml = @Model.UserIconHTML;  

enter image description here

ご覧のとおり、RajTrueはJavaScript変数であると見なされ、variable undefinedエラーは存在しません。 dateTime変数に関してはエラーはunexpected number数字が特殊文字を持つことができないところです。ブラウザがあなたの値とHTMLマークアップを混同しないようにHTMLタグはそのエンティティ名に変換されます。

2)引用符でプロパティの割り当てを囲みます。

var Name = '@Model.Name';
var Age = '@Model.Age';
var LoginTime = '@Model.LoginDateTime';
var IsAuthenticated = '@Model.IsAuthenticated';
var IconHtml = '@Model.UserIconHTML'; 

enter image description here

結果は有効です。そのため、プロパティの割り当てを引用符で囲むと、有効な構文が得られます。ただし、Number Ageは文字列になっているので、引用符を削除するだけでいいので、数値型として表示されます。

3)@Html.Rawを使うが引用符で囲まずに

 var Name = @Html.Raw(Model.Name);
 var Age = @Html.Raw(Model.Age);
 var LoginTime = @Html.Raw(Model.LoginDateTime);
 var IsAuthenticated = @Html.Raw(Model.IsAuthenticated);
 var IconHtml = @Html.Raw(Model.UserIconHTML);

enter image description here

結果は、テストケース1と似ています。ただし、HTML文字列で@Html.Raw()を使用しても、若干の変更が見られました。 HTMLはそのエンティティ名を変更せずに保持されます。

ドキュメントからHtml.Raw()

HTMLマークアップとして解釈されるように、HTMLマークアップをHtmlStringインスタンスにラップします。

しかし、それでも他の行には誤りがあります。

4)@Html.Rawを使用し、それを引用符で囲む

var Name ='@Html.Raw(Model.Name)';
var Age = '@Html.Raw(Model.Age)';
var LoginTime = '@Html.Raw(Model.LoginDateTime)';
var IsAuthenticated = '@Html.Raw(Model.IsAuthenticated)';
var IconHtml = '@Html.Raw(Model.UserIconHTML)';

enter image description here

結果はすべてのタイプに適しています。しかし、HTMLデータは壊れているため、スクリプトが壊れます。問題は、データをラップするために単一引用符'を使用していること、そしてデータにさえ単一引用符があることです。

2つのアプローチでこの問題を克服することができます。

1)HTML部分をラップするために二重引用符" "を使用します。内部データには一重引用符しかありません。 (二重引用符で囲んだ後も、データ内に"がないことを確認してください)

  var IconHtml = "@Html.Raw(Model.UserIconHTML)";

2)サーバーサイドコードの文字の意味をエスケープします。好き

  UserIconHTML = "<i class=\"fa fa-users\"></i>"

プロパティ割り当ての終了

  • 非数値のdataTypeには引用符を使用してください。
  • 数値dataTypeに引用符を使用しないでください。
  • HTMLデータをそのまま解釈するにはHtml.Rawを使用してください。
  • サーバー側で引用符の意味をエスケープするか、JavaScript変数への代入時にデータとは異なる引用符を使用するように、HTMLデータに注意してください。

オブジェクト割当

代入に異なる構文を使用して結果を観察しましょう。

1)オブジェクト割り当てを引用符で囲まないでください。

  var userObj = @Model; 

enter image description here

C#オブジェクトをjavascript変数に割り当てると、そのオブジェクトの.ToString()の値が割り当てられます。したがって上記の結果です。

2オブジェクト割り当てを引用符で囲む

var userObj = '@Model'; 

enter image description here

3)引用符なしでHtml.Rawを使用する。

   var userObj = @Html.Raw(Model); 

enter image description here

4)引用符と一緒にHtml.Rawを使う

   var userObj = '@Html.Raw(Model)'; 

enter image description here

Html.Rawは、オブジェクトを変数に代入する間、あまり役に立ちませんでした。

5)引用符なしでJson.Encode()を使う

var userObj = @Json.Encode(Model); 

//result is like
var userObj = {&quot;Name&quot;:&quot;Raj&quot;,
               &quot;IsAuthenticated&quot;:true,
               &quot;LoginDateTime&quot;:&quot;\/Date(1482572875150)\/&quot;,
               &quot;Age&quot;:26,
               &quot;UserIconHTML&quot;:&quot;\u003ci class=\&quot;fa fa-users\&quot;\u003e\u003c/i\u003e&quot;
              };

私たちはモデルがオブジェクトとして解釈されているのを見ます。しかし、これらの特殊文字をentity namesに変更しました。上記の構文を引用符で囲むこともあまり役に立ちません。引用符で囲んでも同じ結果が得られます。

Json.Encode()のドキュメントから

データオブジェクトをJavaScript Object Notation(JSON)形式の文字列に変換します。

あなたはすでにプロパティの割り当てに関してこのentity Nameの問題に遭遇しているので、覚えているなら我々はHtml.Rawの使用でそれを克服しました。それでは試してみましょう。 Html.RawJson.Encodeを組み合わせることができます

6)引用符なしでHtml.RawおよびJson.Encodeを使用する。

var userObj = @Html.Raw(Json.Encode(Model));

結果は有効なJavascriptオブジェクト

 var userObj = {"Name":"Raj",
     "IsAuthenticated":true,
     "LoginDateTime":"\/Date(1482573224421)\/",
     "Age":26,
     "UserIconHTML":"\u003ci class=\"fa fa-users\"\u003e\u003c/i\u003e"
 };

enter image description here

7)引用符内にHtml.RawJson.Encodeを使用する。

var userObj = '@Html.Raw(Json.Encode(Model))';

enter image description here

ご覧のとおり、引用符で囲むとのJSONデータが得られます

オブジェクト割り当てについての考察

  • Html.RawJson.Encodeを組み合わせて、JavaScriptオブジェクトとしてJavaScriptの変数にあなたのオブジェクトを割り当てることができます。
  • Html.RawおよびJson.Encodeを使用して、JSONを取得するためにもquotes内にラップします。

注:DataTimeデータ形式が正しくないことが確認できた場合。これは、前述のようにConverts a data object to a string that is in the JavaScript Object Notation (JSON) formatとJSONがdate型を含まないためです。これを修正する他のオプションは、javascipt Date()オブジェクトを使用して、この型だけを処理するコードをもう1行追加することです。

var userObj.LoginDateTime = new Date('@Html.Raw(Model.LoginDateTime)'); 
//without Json.Encode


.jsファイルのJavascript/Jqueryコードブロックのモデルデータにアクセスする方法

Razorの構文は.jsファイルでは意味がないため、.jsファイルを使用してモデルを直接使用することはできません。ただし、回避策があります。

1)解決策はjavascriptグローバル変数を使っています。

グローバルスコープのjavascipt変数に値を割り当ててから、この変数を.cshtmlおよび.jsファイルのすべてのコードブロック内で使用する必要があります。したがって、構文は次のようになります。

<script type="text/javascript">
  var userObj = @Html.Raw(Json.Encode(Model)); //For javascript object
  var userJsonObj = '@Html.Raw(Json.Encode(Model))'; //For json data
</script>

これで、必要に応じて変数userObjuserJsonObjを使用できます。

注:保守が非常に困難になるので、個人的にはグローバル変数の使用は推奨しません。ただし、他に選択肢がない場合は、適切な命名規則を使用してそれを使用できます。userAppDetails_globalのようなものです。

2)function()またはclosureを使う関数内のモデルデータに依存します。そして.cshtmlファイルからこの関数を実行します。

external.js

 function userDataDependent(userObj){
  //.... related code
 }

.cshtmlファイル

 <script type="text/javascript">
  userDataDependent(@Html.Raw(Json.Encode(Model))); //execute the function     
</script>

注:上記のスクリプトの前に外部ファイルを参照する必要があります。そうでなければ、userDataDependent関数は未定義です。

関数もグローバルスコープ内になければならないことにも注意してください。そのため、どちらの解決策でも、世界規模のプレーヤーに対処する必要があります。

98
Rajshekar Reddy

これを試してください:(あなたは一重引用符を逃しました)

var floorplanSettings = '@Html.Raw(Json.Encode(Model.FloorPlanSettings))';
18
tennisBoy

モデルのプロパティを親の周りにラップすることは私にとって役に立ちました。あなたはまだセミコロンについて不平を言うVisual Studioで同じ問題を得るが、それはうまくいく。

var closedStatusId = @(Model.ClosedStatusId);
3
FROgistics

"ReferenceError:Model is defined"エラーが発生した場合は、次の方法を試してください。

$(document).ready(function () {

    @{  var serializer = new System.Web.Script.Serialization.JavaScriptSerializer();
         var json = serializer.Serialize(Model);
    }

    var model = @Html.Raw(json);
    if(model != null && @Html.Raw(json) != "undefined")
    {
        var id= model.Id;
        var mainFloorPlanId = model.MainFloorPlanId ;
        var imageDirectory = model.ImageDirectory ;
        var iconsDirectory = model.IconsDirectory ;
    }
});

お役に立てれば...

0
Murat Yıldız