2013-03-27 2 views
7

So. Когда-то было четыре волшебных существа: asp.net mvc, require.js и угловые. И один мудрый волшебник решил поместить их в один и тот же дом, и пусть каждый взгляд на asp.net должен иметь свой собственный javascript-файл с кодом «позади»;сказка о mvc, require.js и угловая. есть ли когда-нибудь?

первым он добавил к _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"]); 
    }); 
}); 

и здесь приходит волшебство: от теперь, если это был файл javascript в \ Scripts \ views, названный как controllerName-viewName.js, как home-index.js для Home \ Index.cshtml, он был бы автоматически захвачен require.js и загружен. Прекрасно, не так ли?

Но тогда волшебник подумал: «Что, если мне нужно загрузить что-то еще (например, ng-grid) и что что-то не следует вводить в общий угловой модуль, потому что не все страницы будут его использовать. Конечно, он всегда мог вручную загружать другой модуль в элемент страницы в каждом javascript-коде, где он нужен, но он недостаточно умен, чтобы найти ответ на вопрос: Можно ли добавить некоторый компонент angular.js (например, ng -grid) непосредственно в контроллер, не имея его как часть модуля приложения?

+1

Я думал, что было четыре волшебных существа, где был другой (asp.net mvc, require.js и угловой)? –

+1

четвертый был '' – Agzam

ответ

1

Если я понимаю magician's Идея права, то можно продолжить, разделив ваше приложение на подмодули, определяемые как набор компонентов.

Это будет работать, если он устанавливает зависимости для основного модуля 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', []); 

Таким образом, основной модуль приложения загружен несколькими подмодулями, но каждая структура не имеет значения. Это позволяет включать в себя отдельные контроллеры, службы, директивы и фильтры на каждой странице, обслуживаемой с помощью внешнего сервера. magician просто должен быть уверен, что загружены все необходимые зависимости.

+0

можно ли хотя бы «загрузить» контроллер? Итак, что происходит сейчас. Если я 'требую' файл, который имеет функцию контроллера в глобальной области действия - он работает. Но как только я решил «определить», он не может найти функцию контроллера. Очень странно – Agzam

+0

И в том месте, где я инициализирую и загружаю приложение, я не знаю точно, какие файлы содержат код для контроллеров, потому что у каждого представления есть или нет файла js с кодом «с кодом» с контроллером или без него , – Agzam

+0

На самом деле я еще не делал ленивой загрузки. Взгляните на эту реализацию: https://github.com/matys84pl/angularjs-requirejs-lazy-controllers. Автор изменил директивы 'ngView' и' ngController' и использовал 'routeConfig', чтобы это сделать. Надеюсь, это поможет вам заставить его работать –

0

DI - это волшебный ключ для раздельного углового кода в виде MVC. Вам даже не нужны требования, потому что углы - это инжекторы зависимостей и загрузчик модулей по своей природе, 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 

см полный аннотированный источник угловыми-scenario.js от https://github.com/angular/bower-angular-scenario, и вы увидите, как вводить код с определения СПОСОБОМ хелперы.

Смежные вопросы