在 JavaScript 代码中使用 Url.Action 的更好解决方案

22
在我的当前项目中,我使用asp.net MVC 3 (使用razor)。当我进行Ajax调用时,我必须将JS保留在视图页上,因为我希望使用Url.Action生成URL。这意味着我不能将js代码拆分到.js文件中,有比我当前所做的更好的解决方案吗?

Simon,我最近回答了这个问题,但实际上发现被接受的答案是一个更简洁的解决方案。请看这里,这是一个不错的简单解决方案:https://dev59.com/WG445IYBdhLWcg3w7unD#4625478。干杯! - jim tollan
4个回答

17

我倾向于以类似的方式完成这个任务,只是稍微有点不同,因为我喜欢给我的JavaScript命名空间。

JavaScript文件大致如下:

var my = {};

my.viewname = 
{
   init : function(settings){
      // do some work here. settings.someImportantUrl has my json/ajax url eg.
      alert(settings.someImportantUrl );
   }
}

那么我的视图将包含类似以下的内容:

<script language='javascript'>
  // allocate an object with variables you want to use in the external js file
  var settings = {someImportantUrl: '<%=Url.Action(...)%>'};
  // call an init method for the current view
  my.viewname.init(settings);
</script>

那么,jamiec,为了再次从JS中提取URL,我只需使用JS对象表示法,例如var url = my.namespace.settings.UserEditUrl,这样正确吗? - Simon
@Simon - 在init方法中,您可以使用settings.whatever来访问您已经分配给视图的变量到设置对象中。重新阅读示例,应该很清楚了。 - Jamiec
Jamie,只是补充一下,你当然要在你的初始JavaScript文件部分添加var my = {}; :-) - jim tollan
我想我会采纳你的建议,Jamie。不过有一个离题的问题,为什么要给JS命名空间,这有什么好处呢?谢谢。 - Simon
2
@Simon - 命名空间为任何编程带来的是组织、清晰和良好的实践。 - Jamiec

9

您可以在视图中仅定义URL,并将所有其他JavaScript代码保留在.js文件中。

以下是我的MVC.NET 1应用程序中的视图代码:

<script type="text/javascript" src="<%=Url.Content("~/Scripts/Account/ManageUsers.js")%>"></script>

<script type="text/javascript" src="<%=Url.Content("~/Scripts/Account/ManageUsersAndGroups.js")%>"></script>

<script type="text/javascript">

    var getUsersUrl = '<%= Url.Action("GetUsers", "Account") %>';
    var getUserDetailsURL = '<%= Url.Action("GetUserDetails", "Account") %>';

    <%If Not ViewData("readOnly") Then%>
    var changeRolePermissionsUrl = '<%= Url.Action("ChangeRolePermissions", "Account") %>';
    var deleteUserUrl = '<%= Url.Action("DeleteUser", "Account") %>';
    var resetPasswordUrl = '<%= Url.Action("ResetPassword", "Account") %>';
    var updateUserGroupsUrl = '<%= Url.Action("UpdateUserGroups", "Account") %>';
    var updateUserDetailsUrl = '<%= Url.Action("UpdateUserDetails", "Account") %>';
    <%End If%>  
</script>

因为安全原因,您甚至可以不为用户无法调用的操作呈现url。(ViewData("readOnly") 表示用户只能读取屏幕内容)。

以下是js文件中的一部分代码:

function GetUsersList() {
    ajax.getJSON(getUsersUrl, {}, function(data) {
        if (data != false) {
            ShowUsers(data);
        }
        else {
            jAlert('Error during users list retrieving.');
        }
    });
}

在View中定义了getUsersUrl


我正在考虑这些方面,即在共享的ascx中保留所有我的Ajax URL集合并进行维护,我只是想确保我没有错过其他可能更容易的方法。 - Simon
我没有看到更好的方法,但是我可以说我的实践很好。它已经在一个大项目中使用了大约1.5年,我们在开发和维护方面都没有任何问题。 - Egor4eg
这是我得到的最佳解决方案。谢谢 @Egor4eg - Rajan Mishra

1
我不确定这样做是否会对安全造成影响,但另一种方法是使用@Url.Action来设置HTML标记的“id”,然后您可以创建一个JavaScript点击函数,如下所示:

查看

<div class="someClickable" id='@Url.Action("Action", "Controller")'>
</div>

引用的 JavaScript 文件

$(function() {
    $('someClickable').click(function () {
        $.ajax({
            url: this.id,
            success: someJSFunction,
            dataType: "html"
        });
    });
});

当你执行只读操作时,将所需的URL存储在“div”的“id”中似乎是一个合理的解决方案。


1

你的 JavaScript 代码应该放在单独的 JavaScript 文件中。你可以使用全局变量来链接你的视图和 JavaScript。例如,视图页面如下所示。

view html ...
<script type="text/javascript">
var pageUrl = @GetURL()
</script>

<script type="text/javascript" src="/js/script.js"/>

script.js 文件使用 pageUrl 变量和其他全局变量。


但我仍然需要在JS文件中硬编码URL路径,而我不想这样做,我希望MVC为我创建URL。 - Simon
@Simon 不需要在js中硬编码路径,因为MVC生成的视图中定义了全局变量。 - Adeel
啊好的,Adeel,你的建议类似于下面Egor4eg的回答。 - Simon

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接