【发布时间】:2013-03-27 15:43:16
【问题描述】:
所以。从前有四种神奇的生物:asp.net mvc、require.js 和 angular。一个聪明的巫师决定把它们放在同一个房子里,让 asp.net 的每个视图都有自己的“代码隐藏”javascript 文件;
首先他添加到_Layout.cshtml
<script data-main="/main" src="~/Scripts/require.js"></script>
然后他在根目录下创建了main.js:
require.config({
baseUrl: "/Scripts/",
paths: {
'jquery': 'jquery-1.9.1.min',
'jquery-ui': 'jquery-ui-1.10.2.custom.min',
'angular': 'angular.min',
'ng-grid': 'ng-grid-2.0.2.debug'
},
shim: {
'jquery': { exports: "$" },
'underscore': { exports: "_" },
'jquery-ui': ['jquery'],
},
});
// Standard Libs
require(['jquery','jquery-ui','underscore','angular']);
还没有什么花哨和神奇的东西。但随后他创建了一个 html 助手:
public static MvcHtmlString RequireJs(this HtmlHelper helper)
{
var controllerName = helper.ViewContext.RouteData.Values["Controller"].ToString(); // get the controllername
var viewName = Regex.Match((helper.ViewContext.View as RazorView).ViewPath, @"(?<=" + controllerName + @"\/)(.*)(?=\.cshtml)").Value; //get the ViewName - extract it from ViewPath by running regex - everything between controllerName +slash+.cshtml should be it;
// chek if file exists
var filename = helper.ViewContext.RequestContext.HttpContext.Request.MapPath("/Scripts/views/" + controllerName.ToLower() + "-" +
viewName.ToLower()+".js");
if (File.Exists(filename))
{
return helper.RequireJs(@"views/" + controllerName.ToLower() + "-" + viewName.ToLower());
}
return new MvcHtmlString("");
}
public static MvcHtmlString RequireJs(this HtmlHelper helper, string module)
{
var require = new StringBuilder();
require.AppendLine(" <script type=\"text/javascript\">");
require.AppendLine(" require(['Scripts/ngcommon'], function() {");
require.AppendLine(" require( [ \"" + module + "\"] );");
require.AppendLine(" });");
require.AppendLine(" </script>");
return new MvcHtmlString(require.ToString());
}
然后他可以像这样在_Layout.cshtml 中使用它:
@Html.RequireJs()
如果你仔细听故事,你可能注意到还有Scripts/ngcommon.js 文件可以手动引导 angular.js 并有常用的 angular 指令和服务
require(['angular', 'jquery'], function() {
angular.module("common",[]).directive('blabla', function() {
return {
restrict: 'A',
scope: { value: "@blabla" },
link: function(scope, element, attrs) { }
}
});
//manually bootstrap it to html body
$(function(){
angular.bootstrap(document.getElementsByTagName('body'), ["common"]);
});
});
魔法来了:从现在开始,如果它是 \Scripts\views 中名为 controllerName-viewName.js 的 javascript 文件,在 Home\Index.cshtml 中为 home-index.js,它将被 require.js 自动拾取并加载。是不是很漂亮?
然后魔术师想:如果我需要加载其他东西(比如 ng-grid)并且不应该将某些东西注入到常见的 Angular 模块中,因为并非所有页面都会使用它。当然,他总是可以手动将另一个模块引导到他需要的每个代码隐藏 javascript 中的页面元素中,但他不够聪明,无法找到问题的答案: 是否可以将一些 angular.js 组件(如 ng-grid)直接注入控制器,而不将其作为应用模块的一部分?
【问题讨论】:
-
我以为有四种神奇的生物,另一种在哪里(asp.net mvc、require.js 和 angular)?
-
第四个是
<hidden/>
标签: asp.net-mvc-4 angularjs requirejs