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

Posted

技术标签:

【中文标题】asp.net-mvc:js文件中的剃刀\'@\'符号【英文标题】:asp.net-mvc: razor '@' symbol in js fileasp.net-mvc:js文件中的剃刀'@'符号 【发布时间】:2011-12-15 16:14:54 【问题描述】:

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

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

【问题讨论】:

也许这有帮助(见答案)***.com/questions/7892793/ajax-succes-function 【参考方案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
);

通过这种方式,您可以在标记和脚本之间进行纯粹的分离,而无需在您的 javascript 文件中添加任何服务器端标签。

【讨论】:

谢谢。我认为对于多个值可能会令人头疼。首先,我认为它可以解决我的问题,但在尝试之后,我发现我的代码中有很多推荐,并决定寻找另一种方法。【参考方案2】:

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

Nuget 包


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

【讨论】:

你能调查一下吗? ***.com/questions/27702322/… 第一个链接坏了 @MemetOlsen,确实,很抱歉,但我找不到它的副本,所以我删除了它:( @gdoron,没问题。我只是想让你知道死链接。正如您所说,该软件包已经 5 年没有更新了,所以无论如何使用它可能是个坏主意。【参考方案3】:

解决问题的一种方法是:

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

【讨论】:

这个不行,局部视图会被渲染,JS最后会在主HTML中...【参考方案4】:

你有两个选择:

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

例如:

 var MyCompany = 
 
   MyProject: 
                  MyVariable:""
               
  ;

然后在你看来,设置它:

MyCompany.MyProject.MyVariable = @....

更新

你可能想知道因为耦合没有任何好处,这是真的,你正在耦合 js 和视图。这就是为什么脚本必须不知道它们运行的​​位置,因此这是文件组织非最佳的症状。

无论如何,还有第三个选项可以创建视图引擎并针对剃须刀运行 js 文件并将结果发回。这更干净但速度慢得多,因此也不推荐。

【讨论】:

+1 我采用第一种方法。从您的视图调用初始化函数,传入您需要的所有数据。 谢谢,第二种方法是不是视图和js文件之间的耦合不好?你有更好的办法吗? 两者都是耦合的。除非在渲染之前编写视图引擎来处理 js 文件,否则无法解耦。查看我的更新。 我建议的这种方式怎么样? ***.com/questions/7902213/… 听起来不错。我的+1。无论是部分视图还是完整视图,都不会改变任何内容。都是js的耦合视图。【参考方案5】:

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

JavaScript 文件:

var myValue;

function myFunc() 
  alert(myValue);

MVC 查看文件:

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

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

【讨论】:

直接将 myValue 作为参数传递给函数怎么样?与依赖全局变量相比,我更喜欢使用参数进行显式调用,但是我对 javascript 不太热衷,因此我可能会错过拥有全局变量的一些重要方面。 @BigMike:当然可以接受。我上面提出的方法只是使变量同时可用于多个函数,但使用参数也一样好。 感谢您的澄清。自动拥有某种 js 对象版本的模型会很棒(通过模型类中的 Attributes 会很棒),这只会添加一个模式和一个完全命名空间感知的变量解决方案。我猜最大的问题是如何将代码注入到发送到浏览器的生成的 html 中(直接通过 @BigMike:这应该很容易通过使用 DataContractJsonSerializer 类 (msdn.microsoft.com/en-us/library/…) 来完成。它会创建一个可以解析到视图中的类的 JSON 版本。【参考方案6】:

这可能不是正确的方法。考虑关注点分离。你的JavaScript 类上应该有一个data injector,在大多数情况下数据是JSON

在您的script 文件夹中创建一个JS 文件并将此引用添加到您的View

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

现在,考虑 yourJsFile.js 中的 JavaScript 文字类:

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>

【讨论】:

不错!但我认为这太复杂了......你觉得我的回答怎么样? ***.com/questions/7902213/…。顺便说一句,您在 setContentB 中有复制粘贴错误,您编写了 contentAData。谢谢! @gdoron 相信我,当你有一个巨大的项目时,管理 JS 类并考虑分离是一个救命稻草【参考方案7】:

我最近写了一篇关于这个主题的博客:Generating External JavaScript Files Using Partial Razor Views。

我的解决方案是使用自定义属性 (ExternalJavaScriptFileAttribute),它按原样呈现部分 Razor 视图,然后在没有周围的 &lt;script&gt; 标记的情况下返回它。这使它成为一个有效的外部 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 文件,因此您拥有的任何使用 @ 的东西都将不起作用。另外,正如您所发现的,Javascript 本身不喜欢这个 @ 字符无缘无故地挂在周围,比方说,在一个字符串中。

【讨论】:

以上是关于asp.net-mvc:js文件中的剃刀'@'符号的主要内容,如果未能解决你的问题,请参考以下文章

将自定义属性添加到 asp.net-mvc 中的页面指令

在 asp.net-mvc 中从服务器读取文本文件的最佳方法是啥

ASP.NET-MVC中Entity和Model之间的关系

如何将消息从我的存储库类返回到我的控制器,然后返回到我在 asp.net-mvc 中的视图?

在 asp.net-mvc 中,查询字符串太长会导致 404 File not found 错误吗?

剑道 DropDownListFor() 与 ASP.NET-MVC