web-dev-qa-db-ja.com

ルートグループに基づいてコントローラーを動的にロードします

コントローラー、そのjsファイル、およびテンプレートをルートグループに基づいて動的にロードすることは可能ですか?動作しない擬似コード:

$routeProvider.when('/:plugin', function(plugin) {
  templateUrl: 'plugins/' + plugin + '/index.html',
  controller: plugin + 'Ctrl',
  resolve: { /* Load the JS file, from 'plugins/' + plugin + '/controller.js' */ }
});

私はこのような質問をたくさん見ましたが、ルートグループに基づいてjsファイル/コントローラーをロードする質問はありません。

9
nilzen

@ calebboyd、 http://ify.io/lazy-loading-in-angularjs/ および http://weblogs.asp.net/dwahlin/)に触発されて、なんとか解決できました。 archive/2013/05/22/dynamicly-loading-controllers-and-views-with-angularjs-and-requirejs.aspx

使用 http://dustindiaz.com/scriptjs

app.js

app.config(function($controllerProvider, $compileProvider, $filterProvider, $provide) {
  app.register = {
    controller: $controllerProvider.register,
    directive: $compileProvider.directive,
    filter: $filterProvider.register,
    factory: $provide.factory,
    service: $provide.service
  };
});

次に、「グループごとのロードコントローラ」ルートを登録します。

$routeProvider.when('/:plugin', {

  templateUrl: function(rd) {
    return 'plugin/' + rd.plugin + '/index.html';
  },

  resolve: {
    load: function($q, $route, $rootScope) {

      var deferred = $q.defer();

      var dependencies = [
        'plugin/' + $route.current.params.plugin + '/controller.js'
      ];

      $script(dependencies, function () {
        $rootScope.$apply(function() {
          deferred.resolve();
        });
      });

      return deferred.promise;
    }
  }
});

controller.js

app.register.controller('MyPluginCtrl', function ($scope) {
  ...
});

index.html

<div ng-controller="MyPluginCtrl">
  ...
</div>
15
nilzen

これを行うには、RequireJSを使用できます。何かのようなもの:

$routeProvider.when('/:plugin',{
    templateUrl: 'plugins/' + plugin + '/index.html',
    controller: plugin + 'Ctrl',
    resolve: {myCtrl: function($q){
        var deferred = $q.defer();
        require('myCtrlFile',function(){
            deferred.resolve();
        });
        return deferred.promise;
    }}
});

また、コントローラーを動的に登録する必要があります。アプリ構成でプロバイダーを公開する。

app.config(function($controllerProvider,$compileProvider,$filterProvider,$provide){
    app.register =
        {
            controller: $controllerProvider.register,
            directive: $compileProvider.directive,
            filter: $filterProvider.register,
            factory: $provide.factory,
            service: $provide.service
        };
});

コントローラファイルは次のようになります。

define(['app'],function(app){
    app.register.controller('myCtrl',MyCtrlFunction);
});

これは単なる一般的な考え方です。説明したものと同様の実装を使用します ここ

私もui-routerを使っています。動作がngRouteと同じかどうかはわかりません。

3
calebboyd

このコードに対して実行できる解決策は次のとおりです。

$routeProvider.when('/:plugin', function(plugin) {
  templateUrl: 'plugins/' + plugin + '/index.html',
  controller: fun,
  loadFrom:"assets/controller/myJsController"// this is our custom parameter we are passing to controller to identify the remote controller file.
});

すべてのコントローラーの親関数を作成し、ルート構成(ルート構成のloadFromキー)で定義されているように、この関数内のすべてのコントローラーを呼び出します。

 function fun($scope, $http, $location, $timeout, $route) {
        $timeout(function () {
        var path = $route.current.loadForm;
        $http.get("${pageContext.servletContext.contextPath}/resource/controller/" + path + ".js")
                .then(function (rsp) {
                eval(rsp.data);
                });
        });
        };

assets/controller/myJsController.jsファイルのコードは次のようになります

(function($scope){
//the whole code for controller will be here.
   $scope.message="working."


 })($scope)

親関数では、すべての依存関係を使用する必要があることを覚えておく必要があります。

2
Ranjeet Rana

少ないコードでこれをアクティブにする最も簡単な方法

require.js設定ファイル。

require.config({
    urlArgs: 'v=1.0',
    baseUrl: '/'
});
app.config(['$controllerProvider', '$compileProvider', '$filterProvider', '$provide','$routeProvider',function($controllerProvider, $compileProvider, $filterProvider, $provide,$routeProvider) {
  app.register = {
    controller: $controllerProvider.register,
    directive: $compileProvider.directive,
    filter: $filterProvider.register,
    factory: $provide.factory,
    service: $provide.service
  };
  // Resolver to load controller, service, directive
  var resolveController = function(dependencies) {
      return {
        load: ['$q', '$rootScope', function ($q, $rootScope) {
          var defer = $q.defer();
          require(dependencies, function () {
              defer.resolve();
              $rootScope.$apply();
          });
          return defer.promise;
        }]
      }
  };
  $routeProvider
    .when("/home", {
        templateUrl : "templates/home.html",
        controller: 'HomeCtrl',
        resolve: resolveController(['controller/HomeCtrl'])
    })
    .when("/ContactUs", {
        templateUrl : "templates/ContactUs.html",
        controller: 'ContactUsCtrl',
        resolve: resolveController(['controller/ContactUsCtrl'])
    })
    .when("/About", {
        templateUrl : "templates/About.html",
        controller: 'AboutCtrl',
        resolve: resolveController(['controller/AboutCtrl'])
    });
  $routeProvider.otherwise('/home');
}]);

コントローラは次のようになります。

define(['app'],function(app){
    app.register.controller('HomeCtrl',['$scope',function($scope){
      // Controller code goes here
    }]);
});
0
Sumeet Roy