Asp.net mvc 4 关于mvc、require.js和angular的童话故事。从此有幸福吗?

Asp.net mvc 4 关于mvc、require.js和angular的童话故事。从此有幸福吗?,asp.net-mvc-4,angularjs,requirejs,Asp.net Mvc 4,Angularjs,Requirejs,所以。从前有四种神奇的生物:asp.NETMVC、require.js和angular。一个聪明的向导决定把它们放在同一个房子里,让asp.net的每个视图都有自己的“代码隐藏”javascript文件 首先,他添加到\u Layout.cshtml <script data-main="/main" src="~/Scripts/require.js"></script> 还没有什么新奇和神奇的东西。但随后他创建了一个html助手: public static M

所以。从前有四种神奇的生物:asp.NETMVC、require.js和angular。一个聪明的向导决定把它们放在同一个房子里,让asp.net的每个视图都有自己的“代码隐藏”javascript文件

首先,他添加到
\u Layout.cshtml

 <script  data-main="/main" src="~/Scripts/require.js"></script>
还没有什么新奇和神奇的东西。但随后他创建了一个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());
}
如果你仔细听了这个故事,你可能会注意到还有
脚本/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网格),并且不应该将某些东西注入到公共角度模块中,因为不是所有的页面都会使用它,该怎么办。当然,他总是可以在需要的地方手动将另一个模块引导到javascript后面的每个代码中的页面元素中,但他不够聪明,无法找到问题的答案: 是否可以将angular.js组件(如ng grid)直接注入控制器,而不将其作为应用程序模块的一部分?

如果我正确理解魔术师的想法,则可以将应用程序拆分为定义为组件集合的子模块

如果他为main
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', []);
然后,每个子模块:
服务
等可以使用单个组件进行扩展,如:

myApp.Controllers.controller('MyController', function () {});
myApp.Services.factory('myService', function () {});
myApp.Directives.directive('myDirective', function () {});
myApp.Filters.filter('myFilter', []);
myApp.Constants.constant('myConstant', []);
这样,主应用程序模块加载了几个子模块,但每个结构并不重要。它可以在后端提供的每个页面上包含单独的控制器、服务、指令和过滤器-魔术师只需确保加载了所有需要的依赖项。

DI是在MVC视图中具有单独角度代码隐藏的关键。 您甚至根本不需要requirejs,因为angular本质上是一个依赖注入程序和模块加载程序,angular.bootstrap是一个神奇的起点

所以,让巫师变得更强大的法术-

var TmplController=function($scope,$compile,$http…//任何模块本身
{
this.parts=[“腿”,“臂”,“头];
$scope.dynamicPagetTemplate=函数($compile)
{
$compile('

{{each}

')($scope); } } TmplController.$inject=['$scope','$comple','$http'];//试试腿或头

参考angular-scenario.js的完整注释源代码,您将发现如何使用定义方式帮助器注入代码。

我认为有四种神奇生物,另一种(asp.net mvc、require.js和angular)在哪里?第四种是
是否可以“引导”控制器?如果我
需要一个在全局范围内具有控制器功能的文件,那么现在会发生什么?它可以工作。但是一旦我决定
定义它,它就找不到控制器功能。非常奇怪,在我初始化和引导应用程序的时候,我不知道确切的文件中包含哪些用于控制的代码因为每个视图都有或可能没有“代码隐藏”有或没有控制器的js文件。实际上我还没有做过延迟加载。看看这个实现:。作者更改了
ngView
ngController
指令,并使用
routeConfig
来实现这一点。希望这能帮助您让它正常工作
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', []);
myApp.Controllers.controller('MyController', function () {});
myApp.Services.factory('myService', function () {});
myApp.Directives.directive('myDirective', function () {});
myApp.Filters.filter('myFilter', []);
myApp.Constants.constant('myConstant', []);
  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