因此。曾几何时,有四种神奇的生物: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并且常用角度指令和服务
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中的一个javascript文件,命名为controllerName-viewName.js,为{\ 1}}为Home \ Index.cshtml,它将被需要自动获取.js并加载。美丽不是吗?
然后魔术师想:如果我需要加载其他东西(如ng-grid),并且不应该将某些东西注入到常见的角度模块中,因为并非所有页面都会使用它。当然,他总是可以手动将另一个模块引导到他需要的每个代码隐藏javascript中的页面元素中,但是他没有足够的智慧来找到问题的答案: 是否可以将一些angular.js组件(如ng-grid)直接注入控制器,而不将其作为app模块的一部分?
答案 0 :(得分:1)
如果我理解魔术师的想法,那么可以通过将应用程序拆分为被定义为组件集合的子模块来继续。
如果他为主myApp
模块设置依赖关系,它将起作用:
var myApp = angular.module('myApp', ['Constants', 'Filters', 'Services', 'Directives', 'Controllers']);
myApp.Constants = angular.module('Constants', []);
myApp.Controllers = angular.module('Controllers', []);
myApp.Filters = angular.module('Filters', []);
myApp.Services = angular.module('Services', []);
myApp.Directives = angular.module('Directives', []);
然后每个子模块:Services
等 - 可以用单个组件扩展,如:
myApp.Controllers.controller('MyController', function () {});
myApp.Services.factory('myService', function () {});
myApp.Directives.directive('myDirective', function () {});
myApp.Filters.filter('myFilter', []);
myApp.Constants.constant('myConstant', []);
这样主应用程序模块就加载了几个子模块,但每个结构并不重要。它可以在后端提供的每个页面上包含单独的控制器,服务,指令和过滤器 - 魔术师只需要确保加载所有需要的依赖项。
答案 1 :(得分:0)
DI 是在MVC视图中具有单独的角度代码隐藏的神奇键。 你根本不需要requirejs,因为angular本质上是一个依赖注入器和模块加载器,angular.bootstrap是一个神奇的起点。
所以让巫师使用咒语变得更加强大 - $inject。
var TmplController = function($scope, $compile, $http... // any module itself
{
this.parts = ['legs','arms','head'];
$scope.dynamicPageTemplate = function($compile)
{
$compile('<div><p ng-repeat="each in parts">{{each}}</p></div>' )( $scope );
}
}
TmplController.$inject = ['$scope','$comple', '$http']; //try legs or head
从https://github.com/angular/bower-angular-scenario引用angular-scenario.js的完整注释源,您将找到如何使用define方式帮助器注入代码。