2011-12-19 40 views
17

我正在使用ASP.Net MVC 3 Razor視圖引擎。MVC 3 Razor視圖:從布爾模型值生成JavaScript

我有一個要求,在我的視圖中根據我的View Model中的值生成一些JavaScript代碼。我需要使用的值是一個布爾值,因爲這個例子可以叫它IsSet

所以我想要做的就是根據這個值創建一個JavaScript布爾值,我可以在稍後的腳本中使用它。

請記住,所有下面的示例我有這段代碼在我的視圖頂部...

@{ string IsSet = Model.IsSet ? "true" : "false"; } 

注意:以下例子是JavaScript的。

首次嘗試 ...

var IsSet = @(IsSet); 

...這實際工作中,問題是它打破了自動格式化在VS 2010中(CTRL + E,d)由於格式錯誤JavaScript--正如你所期望的那樣,這是不可接受的。

第二次嘗試 ...

var IsSet = "@(IsSet)"; 

...我知道,JavaScript是聰明的,它會在需要的時候自動分析我的字符串。哎呀,忘了它是一個字符串類型,除空以外的任何其他值都爲真。

第三次嘗試 ...

var IsSet = Boolean("@(IsSet)"); 

....這肯定會工作......不,重新轉換爲非空字符串爲真(糟糕的解析器!)

四嘗試 ...

var IsSet = "@(IsSet)" === "true"; 

最後,一些工作,但它不看起來不錯。

我會用這個,如果需要但最終我的問題是:有沒有更好的方法來處理這種情況?也許,我第一次嘗試的不良行爲只是微軟可能忽略的一些東西?

如果有人對我有第五次嘗試,那會很好。

對我來說,重要的是,自動格式在VS 2010不破

感謝

+0

我不得不同意你的第一次嘗試 - 看起來對我來說最自然,因爲你沒有進行字符串化處理,然後投射一些已經是布爾值的東西!我在Razor/JS代碼中使用過這種技術,它似乎工作正常,我沒有看到自動格式化的任何問題,但我使用ReSharper,因此可能會自動修復它! – 2011-12-19 11:29:10

+0

我使用ReSharper,我仍然遇到自動格式問題,所以我不確定這就是爲什麼你不打格式問題。自動格式化和大小寫問題發生在Pascal框架的Razor變量出現在格式化程序強制執行小寫命名的地方時,如HTML標記名稱或JS代碼(主要是camelCase;特別是格式化程序在自動縮進時啓用發生......所以克里斯,我有一個預感,你可能有不同的場景? – 2015-03-23 18:46:49

回答

7

第1版是其中唯一一個即使他們都工作過,我也會投票,因爲這是最可讀的。不幸的是,我在家裏沒有VS,所以我無法嘗試看看自動格式化問題是什麼,但如果可能的話,我想忽略問題並繼續使用該版本,因爲有代碼沒有任何問題 - 這只是VS而已。 (你是說VS試圖解釋整個事情的JS,從而發現它無效?)

但是,如果你想一些其他的選項:

第五次嘗試...

@{ string IsSet = Model.IsSet ? "true" : ""; } 

var isSet = !!"@(IsSet)"; 
// OR 
var isSet = Boolean("@(IsSet)"); 

使用舊的雙非操作符技巧將字符串值強制爲布爾值 - 因爲您已經指出「true」和「false」都會變爲true,但如果使用「true」和「」(空字符串) - 所以你可以根據你的「第三次嘗試」使用Boolean()

第六次...

@{ string IsSet = Model.IsSet ? "true" : "false"; } 

// helper function at the top of your page: 
function bool(strVal) { 
    return strVal === "true"; 
} 

// variable declaration 
var isSet = bool("@(IsSet)"); 

OK,所以你最終在你的頁面的頂部相當無意義的功能,但它一直實際變量的聲明相當整齊,如果調試客戶端你會看到bool("false")bool("true")

第七嘗試...

我不喜歡提前創建服務器端string IsSet = Model.IsSet ? "true" : "false";的額外步驟。我不知道剃刀語法,但你能說的線沿線的東西:

var isSet = !!"@(Model.IsSet ? "true" : "")"; 
// OR, better: 
var isSet = !!"@(rzrBool(Model.IsSet))"; 
// where rzrBool() is a server-side helper function (that you would create) 
// which returns "true" or "" 

我希望我所有的「努力」的工作,但我又覺得你的「第一次」是最好的選擇。

+0

順便說一句,在你說'@(IsSet)'的地方,括號是否真的必要,或者你能說'@ IsSet'?如果後者可以使每一個變化都更加整潔。 – nnnnnn 2011-12-19 12:23:44

+0

首先,自動格式化的問題是,只有在JavaScript無效時纔會執行任何操作。如果你錯過了一個函數調用中的右括號等,第二,你會回答所有看起來可行的,除了你第七可能需要使用'包裹整個字符串以避免包含引號的問題,這個選項也看起來很討厭。我同意第一個是最好的,但自動格式化太重要了,不能放棄。我可以去布爾函數,因爲我有其他觀點做類似的事情。 – musefan 2011-12-19 12:39:11

+1

我懷疑我的「5b」是你最好的選擇。不需要任何附加功能(客戶端或服務器端),就像您修改服務器端代碼以返回「true」或空字符串而不是「true」或「false」時一樣。 (關於我的7a,是的,你需要在外面使用單引號使VS感到高興,儘管它應該按原樣運行。) – nnnnnn 2011-12-19 12:57:06

0

如何:

@Model.IsSet.ToString().ToLower() 
+0

沒有好的。我假設你的意思是直接在JavaScript塊中使用這個?如果你的意思是替換我的C#剃鬚刀的第一行代碼,那麼它不會在那裏有所作爲 – musefan 2011-12-19 12:07:19

+0

它打印出我的錯誤....也許如果你添加.ToLower()爲false,var something = @ Model.IsSet.ToString()。ToLower(); – 2011-12-19 12:12:38

+0

但是就像我的第一次嘗試,它會打破VS 2010 – musefan 2011-12-19 12:14:55

0
var isSet= @((bool)Model.IsSet?"true":"false"); 
+1

這是一個不好的答案。首先,將'Model.IsSet'強制轉換爲bool是沒有意義的,因爲它已經是bool了。其次,如果你的意思是在JavaScript中這樣做,你仍然會遇到與我第一次嘗試相同的問題(自動格式化中斷) – musefan 2011-12-19 12:45:43

10

到目前爲止所顯示的任何版本(無論是在問題和答案中)都是我會用到的。這是我會怎麼做:

@model MyViewModel 
<script type="text/javascript"> 
    var isSet = @Html.Raw(Json.Encode(Model.IsSet)); 

    // TODO: use the isSet javascript variable here as a standard boolean value 
</script> 

,或者如果您需要您的視圖模型的其他屬性與JavaScript,你可以JSON編碼整個模型進行操作:

@model MyViewModel 
<script type="text/javascript"> 
    var model = @Html.Raw(Json.Encode(Model)); 

    if (model.IsSet) { 
     alert(model.FooBar); 
    } 
</script> 
+0

不錯的選擇,但這仍然會打破JavaScript的自動格式化。此外,因爲它站立,我得到一個錯誤「條件編譯已關閉」...添加括號解決了這部分問題...'@(Html.Raw(Json.Encode(Model.IsSet)));' – musefan 2011-12-19 12:59:05

+2

@musefan,Razor中的Intellisense,特別是當與javascript混合糟糕的時候。這是我很久以前不再擔心的事情。希望微軟將在未來的某個版本中修復它。它發出一些不應該發射的警告。就我個人而言,我專注於編寫正確的代碼,這些代碼不容易受到XSS注入攻擊......並且我知道它將在運行時正常工作,因爲它可以正確編碼所有內容。事實上,VS給了我一些完美有效的代碼警告,這是VS的設計者應該責備的事情,而不是你自己作爲這個代碼的作者。 – 2011-12-19 13:00:48

+0

這是一個不錯的選擇。雖然它打破了自動格式化,只會在一開始就只是一個問題,而沒有其他服務器端代碼混合到JavaScript中。 – nnnnnn 2011-12-19 13:18:19

14

我按倒用相同問題約一個小時。我的最終解決方案相當於以下內容。

var IsSet = @(Model.IsSet.ToString().ToLower()); // Inside JavaScript block 

這不需要額外的代碼。

+2

第一次嘗試的方式與此相同。智能感知不會識別出爲變量初始化寫入的內容,並在分號處顯示紅色的波浪線。 – 2013-06-12 15:45:07

+0

完美的MVC 4. tks – Gandarez 2014-05-07 15:39:03

1

如何:

@Ajax.ToJson(Model.IsSet) 
+0

什麼是@ Ajax.ToJson()'?它不會顯示在我的智能感知或Google中 – musefan 2012-11-29 16:55:24

0

下面是我用,一個JavaScript塊中:

var someValue; 
@{ var someValue= "someValue= " + Model.SomeValue+ ";"; } 
@someValue 
1
var isSet = /true/i.test('@Model.IsSet'); 
  • 單線
  • 手柄之間的情況差異。網絡和JavaScript
  • 工程,支持自動格式(Visual Studio中,和Visual Studio與ReSharper的)
  • 合理的習慣,如果你熟悉JavaScript正則表達式
  • 相當彈性的邏輯錯誤;它應該按照預期執行或拋出JavaScript錯誤(或者可能是Razor編譯錯誤)。
0

我知道這是一個老問題,但沒有一個答案是特別優雅的。

在這些情況下最簡單的解決方案是簡單地將+0附加到您的條件。這隱式地將bool轉換爲int,但由於結果是01,它立即再次由if語句轉回。例如:

// The space is optional 
if (@IsSet +0) { 
    // Do stuff 
} 

分配一個布爾值變量可以實現如下:

// Note the double (not triple) equals, which performs type conversion 
var isSet = @IsSet+0 == true; 

代碼工作,你沒有紅色的波浪線,和Visual Studio的格式是幸福的。