MVC 3 Razor View: создание JavaScript из логического значения модели - PullRequest
17 голосов
/ 19 декабря 2011

Я использую движок представления ASP.Net MVC 3. Razor.

У меня есть требование генерировать некоторый код JavaScript в моем представлении на основе значения в моей модели представления.Значение, которое мне нужно использовать, является логическим, для этого примера давайте назовем его IsSet.

Итак, я хочу создать логическое значение JavaScript на основе этого значения, которое позже можно будет использовать в скрипте.

Имейте в виду, что для всех приведенных ниже примеров у меня есть этот фрагмент кода в верхней части моего представления ...

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

ПРИМЕЧАНИЕ : Все примеры нижеявляются JavaScript.

Первая попытка ...

var IsSet = @(IsSet);

... это на самом деле работает, проблема в том, что она нарушает автоформатирование (CTRL + E, D) в VS 2010 из-за плохо отформатированного JavaScript - как и следовало ожидать, и это недопустимо.

Вторая попытка ...

var IsSet = "@(IsSet)";

... Я знаю, JavaScript умный, он будет автоматически анализировать мою строку при необходимости.Упс, забыл, что это строковый тип, и все, кроме пустых, принимает значение true.

Третья попытка ...

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

.... конечно, это будетwork ... nope, снова преобразуем непустую строку в true (плохой анализатор!)

Четвертая попытка ...

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

Наконец то, что работает,но для меня это выглядит не очень хорошо.

Я воспользуюсь этим, если понадобится, но в конечном итоге мой вопрос: есть ли лучший способ справиться с такой ситуацией?Возможно, нежелательное поведение в моей первой попытке - это просто то, что Microsoft, возможно, упустила из виду?

Если у кого-то есть хорошая и аккуратная пятая попытка для меня, это было бы хорошо.

Для меня важно то, что автоформатирование в VS 2010 не ломается

Спасибо

Ответы [ 9 ]

14 голосов
/ 20 декабря 2011

Я только что боролся с той же проблемой в течение часа. Мое окончательное решение было эквивалентно следующему.

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

Для этого не требуется дополнительный код.

10 голосов
/ 19 декабря 2011

Ни одна из версий, показанных до сих пор (как в вопросе, так и в ответах), я бы не использовал.Вот как я бы это сделал:

@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>
7 голосов
/ 19 декабря 2011

Версия 1 - единственная из тех, за которые я бы проголосовал, даже если бы они все работали, потому что она наиболее читаема человеком.К сожалению, у меня дома нет VS, поэтому я не могу попробовать его, чтобы увидеть, в чем проблема автоформатирования, но если это вообще возможно, я бы хотел проигнорировать проблему и пойти дальше и использовать эту версию, учитывая, что естьничего на самом деле не так с кодом - это просто VS, который запутался.(Вы говорите, что VS пытается интерпретировать все это как JS и, таким образом, находит его недействительным?)

Но если вам нужны другие варианты:

Пятая попытка ...

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

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

Приведите строковое значение в логическое значение с помощью старого трюка с двойным оператором - как вы уже указали, оба значения "true" и "false" станут истинными, но эта проблема исчезнетесли вы используете «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 ""

Я бы ожидал, что все мои "попытки" сработают, но опять же я думаю, что ваша "первая попытка" этолучший вариант.

1 голос
/ 09 октября 2014
var isSet = /true/i.test('@Model.IsSet');
  • Одна строка
  • Обрабатывает разницу в регистре .Net и JavaScript
  • Работает с автоматическим форматированием (Visual Studio и Visual Studio с Resharper)
  • Разумно идиоматично, если вы знакомы с регулярными выражениями JavaScript
  • Довольно устойчив к логическим ошибкам;он должен делать как положено или выдавать ошибку JavaScript (или, возможно, ошибку компиляции Razor).
1 голос
/ 29 ноября 2012

Как насчет:

@Ajax.ToJson(Model.IsSet)
0 голосов
/ 18 августа 2016

Я знаю, что это старый вопрос, но ни один из ответов не является особенно элегантным.

Самое простое решение в этих ситуациях - просто добавить +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;

Код работает, у вас нет красных волнистых линий, и форматировщик Visual Studio счастлив.

0 голосов
/ 06 мая 2013

Вот что я использую внутри блока javascript:

var someValue;
@{ var someValue= "someValue= " + Model.SomeValue+ ";"; }
@someValue
0 голосов
/ 19 декабря 2011
var isSet= @((bool)Model.IsSet?"true":"false");
0 голосов
/ 19 декабря 2011

Как насчет:

@Model.IsSet.ToString().ToLower()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...