7

そう。むかしむかし、asp.net mvc、require.js、angular という 4 つの魔法の生き物がありました。そして、ある賢明な魔法使いは、それらを同じ家に置き、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.jsHome\Index.cshtml と同様に、require.js によって自動的に取得されて読み込まれます。美しいですね。

しかし、マジシャンは次のように考えました: 何か他のもの (ng-grid など) をロードする必要があり、すべてのページがそれを使用するわけではないため、共通の angular モジュールに何かを注入する必要がない場合はどうでしょうか。もちろん、彼は必要に応じて、各コード ビハインド JavaScript のページ要素に別のモジュールを手動でいつでもブートストラップできますが、次の質問に対する答えを見つけるほど賢明ではありません 。 ) アプリ モジュールの一部として持たずに、コントローラーに直接入れますか?

4

2 に答える 2

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', []);

この方法では、メイン アプリケーション モジュールに複数のサブモジュールがロードされますが、各構造は重要ではありません。バックエンドから提供される各ページに、個々のコントローラー、サービス、ディレクティブ、およびフィルターを含めることができます。マジシャンは、必要な依存関係がすべて読み込まれていることを確認するだけで済みます。

于 2013-03-28T14:20:25.953 に答える
0

DIは、MVC ビューで別々の角度分離コードを持つための魔法の鍵です。angular は本質的に依存性インジェクターおよびモジュール ローダーであるため、requirejs はまったく必要ありません。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 の完全な注釈付きソースを参照すると、定義方法ヘルパーを使用してコードを挿入する方法が見つかります。

于 2013-08-25T23:22:22.430 に答える