Asp.net-mvc: символ razor '@' в файле js

У меня есть файл .csHtml -razor с функцией javascript, которая использует функцию @Url.Content С# внутри URL-адреса ajax.
Я хочу переместить эту функцию в файл .js, ссылающийся на мое представление.

Проблема в том, что javascript не "знает" символ @ и не анализирует код С#.
Есть ли способ ссылаться на .js файлы из представления с символом "@"?

Ответ 1

Вы можете использовать атрибуты HTML5 data-*. Предположим, что вы хотите выполнить какое-либо действие, когда щелкнут какой-либо элемент DOM, такой как div. Итак:

<div id="foo" data-url="@Url.Content("~/foobar")">Click me</div>

а затем в вашем отдельном файле javascript вы можете ненавязчиво работать с DOM:

$('#foo').click(function() {
    var url = $(this).data('url');
    // do something with this url
});

Таким образом, у вас может быть чистое разделение между разметкой и script, если вам не нужны какие-либо теги на стороне сервера в файлах javascript.

Ответ 2

Ну, я только что нашел двигатель бритвы на nuget, который делает это! Значение решает синтаксис @!
Это имя RazorJS.

Nuget пакет


2016 Обновление:
Пакет не обновлялся в течение 5 лет, а ссылка на сайт проекта была мертва. Я не рекомендую людям больше пользоваться этой библиотекой.

Ответ 3

Один из способов решить эту проблему:

Добавление частичного представления с функциями javascript для представления.
Таким образом, вы можете использовать символ @, и все ваши функции javascript отделены от представления.

Ответ 4

У вас есть два варианта:

  • Используйте значение в качестве параметра в функции и подключении в представлении
  • Создайте пространство имен (вместо переменной общественного уровня, которое считается плохой практикой в ​​JS) и установите это значение в верхней части страницы, а затем используйте его в js

Например:

 var MyCompany = 
 {
   MyProject: {
                  MyVariable:""
               }
  };

И затем, на ваш взгляд, установите его:

MyCompany.MyProject.MyVariable = @....

UPDATE

Вы можете удивиться, что ни один из них не является хорошим из-за сцепления, ну, это правда, вы связываете js и просматриваете. Вот почему сценарии не должны забывать о местоположении, в котором они работают, поэтому это признак неоптимальной организации файлов.

Во всяком случае, существует третий вариант создания механизма просмотра и запуска файлов js против бритвы и отправки результатов обратно. Это чище, но намного медленнее, поэтому не рекомендуется.

Ответ 5

Чтобы получить переменную @ в вашем .js файле, вам нужно будет использовать глобальную переменную и установить значение этой переменной из представления mvc, которое использует этот .js файл.

Файл JavaScript:

var myValue;

function myFunc() {
  alert(myValue);
}

MVC Просмотр файла:

<script language="text/javascript">
    myValue = @myValueFromModel;
</script>

Просто убедитесь, что любые вызовы вашей функции происходят ПОСЛЕ того, как значение было задано в представлении.

Ответ 6

Возможно, это неправильный подход. Учитывая разделение проблем. Вы должны иметь data injector в вашем классе JavaScript, и в большинстве случаев данные JSON.

Создайте JS файл в папке script и добавьте эту ссылку в свой View

<script src="@Url.Content("~/Scripts/yourJsFile.js")" type="text/javascript"></script>

Теперь рассмотрим класс JavaScript literal в yourJsFile.js:

var contentSetter = {
    allData: {},
    loadData: function (data) {
        contentSetter.allData = eval('(' + data + ')');
    },
    setContentA: function () {
        $("#contentA").html(allData.contentAData);
    },
    setContentB: function () {
        $("#contentB").html(allData.contentAData);
    }
};

Также объявить класс

public class ContentData
{
    public string ContentDataA { get; set }
    public string ContentDataB { get; set }
}

Теперь, из вашего Action сделайте следующее:

public ActionResult Index() {
    var contentData = new ContentData();
    contentData.ContentDataA = "Hello";
    contentData.ContentDataB = "World";
    ViewData.Add("contentData", contentData);
}

И с вашего взгляда:

<div id="contentA"></div>
<div id="contentB"></div>

<script type="text/javascript">
    contentSetter.loadData('@Json.Encode((ContentData) ViewData["contentData"])');
    contentSetter.setContentA();
    contentSetter.setContentB();
</script>

Ответ 7

Недавно я писал об этой теме: Генерация внешних файлов JavaScript с использованием частичных просмотров Razor.

Моим решением является использование настраиваемого атрибута (ExternalJavaScriptFileAttribute), который отображает частичное представление Razor как есть, а затем возвращает его без окружающих тегов <script>. Это делает его действительным внешним файлом JavaScript.

Ответ 8

Я обычно обертываю JS, нуждающимся в доступе к свойствам модели, в функциях, а затем передаю @something в представлении. Например

<script type="text/javascript">
function MyFunction(somethingPresentInTheView) {
  alert(somethingPresentInTheView);
}
</script>

в представлении я добавляю вызов функции через (только пример):

<input type='button' onclick="MyFunction('@Model.PropertyNeeded')" />

Ответ 9

Я думаю, что вы застряли в том, чтобы поместить этот JS-код в представление. Парсер Razor, насколько я знаю, не будет смотреть на .js файлы, поэтому все, что вы используете, которое использует @, не будет работать. PLUS, как вы заметили, Javascript сам по себе не любит этот символ @, не зависящий от каких-либо причин, другой, скажем, в строке.