asp.net-mvc:js文件中的剃刀'@'符号


90

我有一个.csHtml带有javascript函数的-razor文件,该文件使用@Url.ContentAjax URL内部的C#函数。
我想将该函数移动到.js我的视图引用的文件中。

问题在于javascript无法“知道”该@符号,也无法解析C#代码。
有没有办法.js从带有“ @”符号的视图中引用文件?


Answers:


87

您可以使用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文件中使用任何服务器端标签。


谢谢。我认为对于多个价值观可能会令人头疼。首先,我认为它可以解决我的问题,但是尝试一下之后,我在代码中发现了很多引荐,并决定寻找另一种方法。
QMaster

19

好吧,我刚刚在nuget上找到了一个剃须刀引擎,就能做到!含义解决@语法!
它的名称是RazorJS

的NuGet


2016年更新:
软件包5年未更新,并且项目站点链接已失效。我不建议人们再使用此库。



第一个链接被打破
Memet的奥尔森

@MemetOlsen,确实,很抱歉,但是我找不到它的副本,所以我将其删除了:(
gdoron支持Monica 16'3

@gdoron,没问题。我只是想让您知道无效链接。如您所述,该软件包5年没有更新,因此无论如何使用它可能是一个坏主意。
Memet Olsen

10

解决该问题的一种方法是:

向视图添加带有javascript函数的局部视图。
这样,您可以使用@符号,并且所有javascript功能都与视图分离。


9

您有两种选择:

  • 使用该值作为函数中的参数并在视图中进行连线
  • 创建一个名称空间(而不是公共级别的变量,该变量在JS中被认为是不好的做法),并在页面顶部设置此值,然后在js中使用它

例如:

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

然后在您看来,对其进行设置:

MyCompany.MyProject.MyVariable = @....

更新

您可能想知道,由于耦合没有任何好处,这是真的,您正在耦合js和view。这就是为什么脚本必须忽略它们的运行位置,所以这是文件的非最佳组织的症状。

无论如何,还有第三种选择来创建视图引擎并针对剃刀运行js文件并将结果发送回去。这比较干净,但速度慢得多,因此也不建议使用。


1
+1我是第一种方法。从您的视图中调用初始化函数,以传递所需的所有数据。
理查德·道尔顿

谢谢,第二种方法在视图和js文件之间耦合良好吗?你有更好的方法吗?
gdoron支持Monica 2011年

两者都是耦合的。除非您在渲染之前编写一个视图引擎来处理js文件,否则就无法解耦。查看我的更新。
Aliostad 2011年


听起来还可以。我的+1。无论部分视图还是全视图,都不会更改任何内容。这都是与js的耦合视图。
Aliostad 2011年

7

为了将@变量放入您的.js文件中,您必须使用全局变量并从使用该.js文件的mvc视图中设置该变量的值。

JavaScript文件:

var myValue;

function myFunc() {
  alert(myValue);
}

MVC查看文件:

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

只要确保对函数的任何调用都在视图设置了值之后发生。


1
直接将myValue作为参数传递给函数呢?我更喜欢使用param进行显式调用,而不是依赖于全局变量,但是我不太喜欢javascript,因此我可能会缺少拥有全局变量的一些重要方面。
2011年

@BigMike:当然可以接受。我上面提出的方法只是简单地使变量同时可用于多个函数,但是使用参数也一样。
乔尔·埃瑟顿

感谢您的澄清。自动具有某种js对象版本的模型会很棒(通过model类中的Attributes会很棒),这只会添加一个模式和一个完全支持名称空间的变量解决方案。我猜最大的问题是如何在发送到浏览器的html中注入代码(直接通过<script>标签)。我想我当前的项目结束后,将对此进行一些实验。
2011年

@BigMike:使用DataContractJsonSerializer类(msdn.microsoft.com/en-us/library/…)应该可以很容易地做到这一点。它将创建您的类的JSON版本,可以将其解析为视图。
乔尔·埃瑟顿

4

可能这不是正确的方法。考虑分离关注点。您应该data injectorJavaScript课堂上使用,大多数情况下数据是JSON

在您的script文件夹中创建一个JS文件,并将此引用添加到您的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>

真好!但我认为这太复杂了……您如何看待我的回答?stackoverflow.com/questions/7902213/…。顺便说一下,您在setContentB中有复制粘贴错误,您编写了contentAData。谢谢!
gdoron在2011年

1
@gdoron相信我,管理JS类,并考虑到当您有一个庞大的项目时,分离可以节省生命
Abdul Munim


2

我通常将需要访问模型属性的JS包装在函数中,然后在视图中传递@something。例如

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

在视图中,我通过添加函数调用(仅作为示例):

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

1

我认为您不得不在视图中放入该JS代码。据我所知,Razor解析器不会查看.js文件,因此您使用的所有内容均@无法使用。正如您所发现的那样,PLus,Java脚本本身不喜欢这个@字符无缘无故地徘徊,例如字符串中。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.