web-dev-qa-db-ja.com

RazorでMVC4を使用してJavaScript変数を設定する方法

誰かがカミソリを使用してC#コードでsrcript変数を設定できるように、誰かが以下のコードをフォーマットできますか?

以下は機能しません。誰かが手助けするのは簡単です。

@{int proID = 123; int nonProID = 456;}

<script type="text/javascript">
    @{

     <text>  

    var nonID =@nonProID;
    var proID= @proID;
    window.nonID = @nonProID;
    window.proID=@proID;

    </text>
}
</script>

設計時エラーが発生しています

enter image description here

かみそりのページが結果として出力されるのを見てください。実際、server-sideおよびclient-sideによって実行される内容を知る必要があります。これを試して:

@{
    int proID = 123; 
    int nonProID = 456;
}

<script>

    var nonID = @nonProID;
    var proID = @proID;
    window.nonID = @nonProID;
    window.proID = @proID;

</script>

出力は次のようになります。

enter image description here

使用しているVisual Studioのバージョンに応じて、かみそりを使用したビューの設計時のハイライトが示されます。

38
Felipe Oriani

これは私が問題を解決した方法です:

@{int proID = 123; int nonProID = 456;}

<script type="text/javascript">
var nonID = Number(@nonProID);
var proID = Number(@proID);
</script>

それは自己文書化されており、テキストへの変換とテキストからの変換を含みません。


注:Number()オブジェクトは作成しないでnew Number()関数を使用するように注意してください-完全に等しい演算子は非自明な方法で動作する可能性があるためです。

var y = new Number(123); // Note incorrect usage of "new"
var x = new Number(123);
alert(y === 123); // displays false
alert(x == y); // displays false
19
Scott Gartner

かみそりの構文エラーは、ビューの作業中に問題になる可能性があるため、それらを回避したい理由は完全にわかります。他にもいくつかのオプションがあります。

<script type="text/javascript">
    // @Model.Count is an int
    var count = '@Model.Count';
    var countInt = parseInt('@Model.ActiveLocsCount');
</script>

引用符は区切り文字として機能するため、カミソリパーサーは満足しています。しかし、もちろん、C#intは最初のステートメントでJS文字列になります。純粋主義者にとっては、2番目のオプションの方が良いかもしれません。

誰かがかみそりの構文エラーなしでこれを行うより良い方法を持っているなら、特に変数の型を維持するなら、私はそれを見たいです!

16
Sean

私はバグを回避するためのいくつかのアプローチを見てきました、そして、速度のために何が機能するかを見るためにいくつかのタイミングテストを実行しました( http://jsfiddle.net/5dwwy/

アプローチ:

  1. 直接割り当て

    このアプローチでは、カミソリ構文は変数に直接割り当てられます。これがエラーをスローするものです。 JavaScriptの速度テストは、ベースラインとして、単純に変数に数値を直接割り当てます。

  2. `Number`コンストラクターを通過します

    このアプローチでは、 `Number(@ ViewBag.Value)`のように、かみそりの構文を `Number`コンストラクターの呼び出しでラップします。

  3. ParseInt

    このアプローチでは、カミソリの構文は引用符で囲まれ、 `parseInt`関数に渡されます。

  4. 値を返す関数

    このアプローチでは、かみそりの構文をパラメーターとして単純に取得して返す関数が作成されます。

  5. 型チェック関数

    このアプローチでは、関数はいくつかの基本的な型チェック(基本的にnullを探す)を実行し、nullでない場合は値を返します。

手順:

上記の各アプローチを使用して、for-loopは各関数呼び出しを10M回繰り返し、ループ全体の合計時間を取得します。次に、forループを30回繰り返して、10Mアクションあたりの平均時間を取得します。次に、これらの時間を相互に比較して、どのアクションが他のアクションよりも速いかを判断しました。

JavaScriptが実行されているため、他の人が受け取る実際の数字は異なりますが、重要性は実際の数字ではなく、数字が他の数字とどのように比較されるかに注意してください。

結果:

直接割り当てアプローチを使用すると、10Mの割り当てを処理する平均時間は98.033msでした。 Numberコンストラクタを使用すると、10Mあたり1554.93msが得られました。同様に、parseIntメソッドは1404.27msかかりました。 2つの関数呼び出しは、単純な関数では97.5ミリ秒、より複雑な関数では101.4ミリ秒かかりました。

結論:

理解する最もクリーンなコードは、直接割り当てです。ただし、Visual Studioのバグのため、これはエラーを報告し、Intellisenseで問題を引き起こし、間違っているという漠然とした感覚を与える可能性があります。

最速のコードは単純な関数呼び出しでしたが、わずかなマージンしかありませんでした。私はこれ以上の分析を行わなかったため、この違いに統計的有意性があるかどうかはわかりません。型チェック機能も非常に高速で、直接割り当てよりもわずかに遅く、変数がnullになる可能性が含まれています。ただし、パラメーターが未定義(カミソリ構文ではnull)の場合、基本関数でさえ未定義を返すため、実際には実用的ではありません。

かみそりの値をintとして解析し、コンストラクターで実行するのは非常に遅く、直接の割り当てよりも15倍のオーダーでした。ほとんどの場合、Numberコンストラクターは実際にparseIntを内部的に呼び出しているため、単純なparseIntよりも時間がかかる理由を説明できます。ただし、外部に定義された(つまり、ファイルまたはアプリケーションのどこかに)関数を実行する必要なく、Numberコンストラクターが実際に整数から文字列。

要するに、これらの数値は1,000万回の反復を通じて生成されました。単一のアイテムでは、速度は計り知れないほど小さいです。ほとんどの場合、Numberコンストラクターを介して単純に実行することは、最も遅いにもかかわらず、最も読みやすいコードです。

12
saluce
@{
int proID = 123; 
int nonProID = 456;
}

<script>

var nonID = '@nonProID';
var proID = '@proID';
window.nonID = '@nonProID';
window.proID = '@proID';

</script>
7
Ahmed Ghazey

次のようなことをすれば機能します:

var proID = @proID + 0;

次のようなコードを生成します:

var proID = 4 + 0;

確かに少し奇妙ですが、少なくとも偽の構文エラーはありません。残念ながら、VS2013でもエラーが報告されているため、まだ適切に対処されていません。

3
mabian69

警告としての答えではなく、これも私を悩ませていました-そして、ゼロを前に付けて@(...)構文を使用することで解決策があると思いました。つまり、あなたのコードは:

var nonID = 0@(nonProID);
var proID = 0@(proID);

次のような出力を取得します。

var nonId = 0123;

私が気付いていなかったのは、これがJavaScript(バージョン3)が8進数/ 8進数を表す方法であり、実際に値を変更していることです。さらに、"use strict";コマンドを使用している場合、8進数が削除されているため、コードが完全に破損します。

私はまだこれに対する適切な解決策を探しています。

3
Rob Church

ロジックとGUIを分離できる非常にクリーンなソリューションを見つけました。

あなたのrazor .cshtmlページでこれを試してください:

<body id="myId" data-my-variable="myValue">

...your page code here

</body>

.jsファイルまたは.ts(TypeScriptを使用する場合)で、保存された値をビューから読み取るために、次のように入力します(jqueryライブラリが必要です)。

$("#myId").data("my-variable")
3
Rafael Rivarola

私はこのアプローチを検討しています:

function getServerObject(serverObject) {
  if (typeof serverObject === "undefined") {
    return null;
  }
  return serverObject;
}

var itCameFromDotNet = getServerObject(@dotNetObject);

私にとって、これはJS側でそれをより安全にしているようです...最悪の場合、null変数で終わることになります。

3
Ryan Young

簡単な方法の1つは次のとおりです。

<input type="hidden" id="SaleDateValue" value="@ViewBag.SaleDate" />
<input type="hidden" id="VoidItem" value="@Model.SecurityControl["VoidItem"].ToString()" />

そして、javascriptで値を取得します。

var SaleDate = document.getElementById('SaleDateValue').value;
var Item = document.getElementById('VoidItem').value;
2
Arsman Ahmad

非常に単純なfunctionを使用して、JavaScriptコードと混在するRazorコードの本体の構文エラーを解決します;)

function n(num){return num;}

var nonID = n(@nonProID);
var proID= n(@proID);
1
RAM

これはすべての主要なタイプをカバーするはずです:

public class ViewBagUtils
{
    public static string ToJavascriptValue(dynamic val)
    {
        if (val == null) return "null";
        if (val is string) return val;
        if (val is bool) return val.ToString().ToLower();
        if (val is DateTime) return val.ToString();
        if (double.TryParse(val.ToString(), out double dval)) return dval.ToString();

        throw new ArgumentException("Could not convert value.");
    }
}

そして、<script>タグ内の.cshtmlファイルで:

@using Namespace_Of_ViewBagUtils
const someValue = @ViewBagUtils.ToJavascriptValue(ViewBag.SomeValue);

文字列値については、次のように、単一引用符(または二重引用符)内で@ViewBagUtils式を使用する必要があることに注意してください。

const someValue = "@ViewBagUtils.ToJavascriptValue(ViewBag.SomeValue)";
1
wm1sr