2011-12-19 12 views
17

Używam mechanizmu wyświetlania maszynki ASP.Net MVC 3 Razor.MVC 3 Razor View: Generowanie kodu JavaScript z wartości modelu boolowskiego

Mam wymóg generowania kodu JavaScript w moim widoku na podstawie wartości w moim modelu widoku. Wartość, której potrzebuję użyć, jest wartością logiczną, w tym przykładzie można ją nazwać IsSet.

Co chcę zrobić, to utworzyć boolean JavaScript w oparciu o tę wartość, której później mogę użyć w skrypcie.

Należy pamiętać, że dla wszystkich poniżej przykłady Mam ten fragment kodu na szczycie moim zdaniem ...

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

UWAGA: Wszystkie poniższe przykłady JavaScript.

Pierwsza próba ...

var IsSet = @(IsSet); 

... to faktycznie działa, problem jest łamie auto-formatowanie (Ctrl + E, D) w VS 2010 z powodu źle sformatowane JavaScript - jak można się spodziewać, a to nie jest dopuszczalne.

Druga próba ...

var IsSet = "@(IsSet)"; 

... Wiem, JavaScript jest mądry, to zostanie automatycznie analizować mój ciąg, gdy są potrzebne. Ooops, zapomniałem, że jest to ciąg znaków, a wszystko inne, niż puste, jest prawdziwe.

Trzecia próba ...

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

.... na pewno to będzie działać ... nope, konwersja niepusty ciąg true ponownie (złe parsera!)

czwarte próbować ...

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

Wreszcie coś, co działa, ale to nie wygląda wspaniale mnie.

Użyję tego w razie potrzeby, ale ostatecznie moje pytanie brzmi: czy istnieje lepszy sposób radzenia sobie z taką sytuacją? Być może niechciane zachowanie w mojej pierwszej próbie jest czymś, co Microsoft przeoczył?

Jeśli ktoś ma miłą i uporządkowaną piątą próbę dla mnie, to byłoby dobrze.

Ważną rzeczą dla mnie jest to, że auto-formatowanie w VS 2010 nie łamie

Dzięki

+0

Muszę się zgodzić z pierwszą próbą - to wygląda dla mnie jak najbardziej naturalnie, ponieważ nie szarpiesz, a potem rzucasz coś, co było już boolowskie! Używałem tej techniki bardzo dużo w moim kodzie Razor/JS i wygląda na to, że działa dobrze i nie widziałem żadnych problemów z automatycznym formatowaniem, ale używam ReSharper, więc może to naprawi automatycznie! –

+0

Używam programu ReSharper i nadal napotykam problem z automatycznym formatowaniem, więc nie jestem pewien, dlaczego nie dotykasz problemów z formatowaniem. Problem z automatycznym formatowaniem i pisaniem wielkimi literami występuje, gdy zmienne Razor-Razd pojawiają się w miejscach, w których formater wymusiłby pisanie małymi literami, takich jak nazwy znaczników HTML lub kod JS (głównie camelCase, w szczególności formater uruchamia się, gdy automatyczne wcięcie występuje ... Więc Chris, mam przeczucie, że mógłbyś mieć inny scenariusz? –

Odpowiedz

7

Wersja 1 jest tylko jednym z tych na które głosowałbym, nawet gdyby wszystkie zadziałały, ponieważ jest to najbardziej czytelne dla człowieka.Niestety nie mam VS w domu, więc nie mogę go wypróbować, żeby zobaczyć, co to jest problem z automatycznym formatowaniem, ale jeśli w ogóle to możliwe, zignorowałbym ten problem i używałbym tej wersji, biorąc pod uwagę, że istnieje nic nie jest w porządku z kodem - to po prostu VS jest zdezorientowany. (Czy mówisz VS próbuje interpretować całość jako JS, a tym samym znalezienie go nieważny?)

Ale jeśli chcesz jakieś inne opcje:

piątej próbie ...

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

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

Zmień wartość ciągu na boolean ze starą metodą double-not-operator - jak już zaznaczyłeś, obie wartości "true" i "false" staną się prawdą, ale ten problem zniknie, jeśli użyjesz "true" i "" (pusty ciąg znaków) - możesz więc użyć Boolean() jako "trzeciej próby".

Szósta próba ...

@{ 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, więc skończyć z dość bezsensownej funkcji w górnej części strony, ale to wciąż aktualne deklaracje zmiennych rozsądnie schludny i jeśli debugowanie po stronie klienta zobaczysz bool("false") lub bool("true").

Siódma próba ...

Nie lubię dodatkowy krok tworzenia stronie serwera string IsSet = Model.IsSet ? "true" : "false"; wyprzedzeniem. Nie wiem składni Razor, ale można powiedzieć coś w rodzaju:

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 "" 

spodziewałbym wszystkich moich „prób” do pracy, ale znowu myślę, że „Pierwsza próba” jest najlepszym rozwiązaniem .

+0

Nawiasem mówiąc, czy nawiasy naprawdę są niezbędne wszędzie, gdzie powiedziałeś '@ (IsSet)', czy możesz po prostu powiedzieć '@ IsSet'? Jeśli ta ostatnia jest w porządku, każda zmiana byłaby lepsza. – nnnnnn

+0

Po pierwsze, problem z automatycznym formatowaniem polega na tym, że po prostu nie robi nic, gdy masz nieprawidłowy JavaScript. To samo by miało zastosowanie, gdybyś pominął nawias zamykający od wywołania funkcji itp. Po drugie, wszystkie odpowiedzi wyglądają na wykonalne, z wyjątkiem tego, że siódmy prawdopodobnie wymagałby użycia "zawinięcia całego ciągu znaków, aby uniknąć problemów z zawieraniem cytatów, również ta opcja wygląda paskudnie . Zgadzam się, że pierwsza jest najlepsza, ale automatyczne formatowanie jest zbyt ważne, aby się poddać. Mogę wybrać funkcję bool, ponieważ mam inne widoki, które robią podobne rzeczy. – musefan

+1

Podejrzewam, że moje "5b" jest najlepszą opcją dla ciebie. Nie wymaga żadnych dodatkowych funkcji (po stronie klienta lub serwera) i przypomina trzecią próbę po zmodyfikowaniu kodu po stronie serwera w celu zwrócenia "true" lub pustego ciągu zamiast "true" lub "false". (Jeśli chodzi o moje 7a, tak, aby uzyskać VS, trzeba użyć cudzysłowów na zewnątrz, ale znowu powinno działać tak jak jest.) – nnnnnn

0

Jak o:

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

No dobrze.Myślę, że chcesz użyć tego bezpośrednio w bloku JavaScript? Jeśli chcesz zastąpić pierwszą linię mojej maszynki do golenia C# kod, to też nie robi różnicy tam. – musefan

+0

wypisuje Fałsz dla mnie .... może jeśli dodasz .ToLower() dla false, var coś = @ Model.IsSet.ToString(). ToLower(); –

+0

Tak, to by działało, ale tak jak moja pierwsza próba, to łamie automatyczne formatowanie w VS 2010 – musefan

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

To jest zła odpowiedź. Po pierwsze nie ma sensu rzutować 'Model.IsSet' na bool, ponieważ jest już bool. Po drugie, jeśli chcesz to zrobić w JavaScript, wciąż masz ten sam problem co moja pierwsza próba (automatyczne formatowanie przerw). – musefan

10

Żadna z wersji przedstawionych do tej pory (zarówno w pytaniu i odpowiedzi) jest coś, co chciałbym użyć. Oto w jaki sposób to zrobić:

@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> 

lub jeśli potrzebne inne właściwości swojego modelu widoku być zmieniane za pomocą JavaScript można JSON zakodować cały model:

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

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

Dobra alternatywa, ale nadal łamie automatyczne formatowanie JavaScript. Ponadto, w obecnej wersji pojawia się błąd "Kompilacja warunkowa jest wyłączona" ... dodane nawiasy rozwiązują tę część problemu ... '@ (Html.Raw (Json.Encode (Model.IsSet)));' – musefan

+2

@musefan, Intellisense in Razor, zwłaszcza gdy pomieszany z javascriptem jest do bani. To jest coś, co przestałem się martwić dawno temu. Mam nadzieję, że Microsoft naprawi to w jakiejś przyszłej wersji. Emituje niektóre ostrzeżenia, które nie powinny być emitowane. Osobiście koncentruję się na pisaniu poprawnego kodu, który nie jest podatny na ataki typu XSS injection ... i który, jak wiem, będzie działał poprawnie w środowisku uruchomieniowym, ponieważ poprawnie koduje wszystko. Fakt, że VS daje mi ostrzeżenia o jakimś doskonale poprawnym kodzie, jest czymś, za co winić należy projektantów VS, a nie samemu jako autorowi tego kodu. –

+0

To jest dobra alternatywa. Chociaż łamie on automatyczne formatowanie, które będzie problemem tylko w jednej linii na samym początku, bez żadnego innego kodu po stronie serwera, który zostanie wstawiony do JavaScript. – nnnnnn

14

Właśnie mocował się z tym samym wydawać około godziny. Moje końcowe rozwiązanie było równoważne poniższym.

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

Nie wymaga dodatkowego kodu.

+2

Spowoduje to złamanie w ten sam sposób, co pierwsza próba. Intellisense nie rozpozna, że ​​coś zostało napisane dla inicjalizacji zmiennych i pokazuje czerwoną falistą linię na średniku. –

+0

Doskonały w MVC 4. tks – Gandarez

1

Jak o:

@Ajax.ToJson(Model.IsSet) 
+0

Co to jest "@ Ajax.ToJson()"? Nie pojawia się w mojej intellisense lub w Google – musefan

0

Oto co mogę używać, wewnątrz bloku javascript:

var someValue; 
@{ var someValue= "someValue= " + Model.SomeValue+ ";"; } 
@someValue 
1
var isSet = /true/i.test('@Model.IsSet'); 
  • Pojedyncza linia
  • Uchwyty różnicę pomiędzy case.Netto i JavaScript
  • Works z auto-formatowania (Visual Studio i Visual Studio z Resharper)
  • Racjonalnie idiomatyczne jeśli jesteś zaznajomiony z JavaScript regexes
  • Dość odporny na błędy logiczne; powinien zrobić to w sposób zamierzony lub zrzucić błąd JavaScript (lub prawdopodobnie błąd kompilacji Razor).
0

Wiem, że to stare pytanie, ale żadna z odpowiedzi nie jest szczególnie elegancka.

Najprostszym rozwiązaniem w tych sytuacjach jest dodanie do warunku wartości +0. To niejawnie konwertuje wartość bool na int, ale ponieważ wynikiem jest 0 lub 1, jest ona natychmiast konwertowana ponownie przez instrukcję if. Przykład:

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

Przypisywanie wartość logiczną do zmiennej można osiągnąć w następujący sposób:

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

Kod działa, masz żadnych czerwone linie falowane, a Visual Studio formater jest szczęśliwy.

Powiązane problemy