MVC 3 Razor View: генерирование JavaScript из значения логической модели
Я использую механизм просмотра ASP.NET MVC 3 Razor.
У меня есть требование генерировать код JavaScript в моем представлении на основе значения в моей модели просмотра. Значение, которое мне нужно использовать, является логическим, так как этот пример позволяет называть его IsSet
.
Итак, что я хочу сделать, это создать логическое выражение JavaScript на основе этого значения, которое я могу использовать в script позже.
Имейте в виду, что для всех приведенных ниже примеров у меня есть этот бит кода в верхней части моего представления...
@{ string IsSet = Model.IsSet ? "true" : "false"; }
ПРИМЕЧАНИЕ. Все приведенные ниже примеры - это JavaScript.
Первая попытка...
var IsSet = @(IsSet);
... это действительно работает, проблема заключается в том, что он прерывает автоматическое форматирование (CTRL + E, D) в VS 2010 из-за плохо отформатированного JavaScript - как и следовало ожидать, и это неприемлемо.
Вторая попытка...
var IsSet = "@(IsSet)";
... Я знаю, JavaScript умен, он будет автоматически анализировать мою строку при необходимости. Ooops, забыли, что это строковый тип, и ничего, кроме пустого, оценивается как true.
Третья попытка...
var IsSet = Boolean("@(IsSet)");
.... конечно, это сработает... nope, конвертировать непустую строку в true снова (плохой парсер!)
Четвертая попытка...
var IsSet = "@(IsSet)" === "true";
Наконец-то что-то работает, но мне это не выглядит здорово.
Я буду использовать это, если нужно, но в конечном итоге мой вопрос: есть ли лучший способ справиться с такой ситуацией? Возможно, нежелательное поведение в моей первой попытке - это то, что Microsoft, возможно, пропустила?
Если у кого-то есть хорошая и аккуратная пятая попытка для меня, это будет хорошо.
Для меня важно то, что автоматическое форматирование в VS 2010 не нарушает
Спасибо
Ответы
Ответ 1
Версия 1 - это единственная из тех, за кого я проголосовал, даже если они все работали, потому что она самая удобочитаемая для человека. К сожалению, у меня нет ВС дома, поэтому я не могу попробовать, чтобы узнать, что такое проблема автоматического форматирования, но если это вообще возможно, я бы хотел проигнорировать проблему и продолжать использовать эту версию, учитывая, что там ничего не случилось с кодом - это просто СБ, что сбито с толку. (Вы говорите, что 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)");
ОК, поэтому вы получаете довольно бессмысленную функцию в верхней части страницы, но она сохраняет корректные порядок объявлений переменных, и если вы отлаживаете клиентскую сторону, вы увидите bool("false")
или bool("true")
.
Седьмая попытка...
Мне не нравится дополнительный шаг создания серверной стороны string IsSet = Model.IsSet ? "true" : "false";
заранее. Я не знаю синтаксиса Razor, но вы можете сказать что-то вроде:
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 ""
Я бы ожидал, что все мои "попытки" будут работать, но я снова думаю, что ваша "первая попытка" - лучший вариант.
Ответ 2
Я просто боролся с той же проблемой около часа. Мое окончательное решение было эквивалентно следующему.
var IsSet = @(Model.IsSet.ToString().ToLower()); // Inside JavaScript block
Это не требует дополнительного кода.
Ответ 3
Ни одна из версий, показанных до сих пор (как в вопросе, так и в ответах), является тем, что я буду использовать. Вот как я это сделаю:
@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>
Ответ 4
Как насчет:
@Ajax.ToJson(Model.IsSet)
Ответ 5
var isSet = /true/i.test('@Model.IsSet');
- Одиночная строка
- Обрабатывает разницу между .Net и JavaScript
- Работает с автоматическим форматированием (Visual Studio и Visual Studio с Resharper)
- Разумно идиоматично, если вы знакомы с регулярными выражениями JavaScript
- Достаточно устойчив к логическим ошибкам; он должен сделать так, как предполагалось, или выбросить ошибку JavaScript (или, возможно, ошибку компиляции Razor).
Ответ 6
Как насчет:
@Model.IsSet.ToString().ToLower()
Ответ 7
var isSet= @((bool)Model.IsSet?"true":"false");
Ответ 8
Вот что я использую внутри блока javascript:
var someValue;
@{ var someValue= "someValue= " + Model.SomeValue+ ";"; }
@someValue
Ответ 9
Я знаю, что это старый вопрос, но ни один из ответов не является особенно элегантным.
Самое простое решение в этих ситуациях - просто добавить +0
к вашему условному. Это неявно преобразует bool в int, но поскольку результат 0
или 1
, он сразу же преобразуется обратно с помощью оператора 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;
Код работает, вы не получаете красных squiggly строк, и форматер Visual Studio счастлив.