asp.net-mvc: символ бритвы '@' в файле js - PullRequest
86 голосов
/ 26 октября 2011

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

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

Ответы [ 9 ]

87 голосов
/ 09 января 2012

Вы можете использовать атрибуты 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
});

Таким образом, вы можете полностью разделить разметку и скрипт без васнужны любые теги на стороне сервера в ваших файлах JavaScript.

18 голосов
/ 27 октября 2011

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

Пакет Nuget


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

10 голосов
/ 26 октября 2011

Один из способов для решения проблемы:

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

9 голосов
/ 26 октября 2011

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

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

Например:

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

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

MyCompany.MyProject.MyVariable = @....

UPDATE

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

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

7 голосов
/ 26 октября 2011

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

Файл JavaScript:

var myValue;

function myFunc() {
  alert(myValue);
}

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

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

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

4 голосов
/ 14 февраля 2014

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

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

4 голосов
/ 26 октября 2011

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

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

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

Теперь рассмотрим буквальный класс JavaScript в вашем 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>
2 голосов
/ 26 октября 2011

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

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

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

<input type='button' onclick="MyFunction('@Model.PropertyNeeded')" />
1 голос
/ 26 октября 2011

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

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