web-dev-qa-db-ja.com

angularjs $ routeProviderにコントローラーを動的にロードする

現在、ルーティングが組み込まれたAngularJSアプリがあり、静的なcontrollerプロパティ割り当てで完全に動作します。しかし、私が本当にやりたいことは、異なるルートを持つコントローラを動的に割り当てることです:

$routeProvider
 .when("/Dashboards/:dashboardName",{
    templateUrl:function(params) {
                 return "Dashboards/" + params.dashboardName;
                //some ASP.NET MVC calls to return partial views (this part works)
        }
  })

私がやりたいのは、ここでcontrollerプロパティについて同じことを行うことです。

$routeProvider
 .when("/Dashboards/:dashboardName",{
       templateUrl:function(params) {
             return "Dashboards/" + params.dashboardName;
            //some ASP.NET MVC calls to return partial views (this part works)
           },
       controller: function(params) {
             return params.dashboardName+"Controller"; (this part DOESN'T work)
           }
  })

しかし、paramsProviderが見つからないというエラーが表示されるようです

それで、ルート構成でコントローラーの関数名を動的にロードする方法はありますか?

21
Kia Panahi Rad

これは angular ui-router を使用して実行できます。

Ui-routerを使用すると、「controllerProvider」を指定して、コントローラーを提供する関数を指定できます。したがって、ソリューションは次のようになります。

$stateProvider
.state("/Dashboards/:dashboardName",{
   templateUrl:function($stateParams) {
         return "Dashboards/" + $stateParams.dashboardName;
       },
   controllerProvider: function($stateParams) {
         return $stateParams.dashboardName+"Controller";
       }
  })

お役に立てば幸いです。

11
Bradley Trager

$ routeProviderでコントローラーを指定せずに、templateURLで指定されたファイルに配置することで、この問題を解決しました。

_$routeProvider
 .when("/Dashboards/:dashboardName",{
    templateUrl:function(params) {
                 return "Dashboards/" + params.dashboardName;
        }
  })
_

_DashboardsNAME.html_内

_<div class="container" ng-Controller='DashboardsNAMEController'>Food</div>
_

この手法では、ルートがインスタンス化される前のある時点で、DashboardsNAMEControllerを登録する必要があります。それを行うのに最適な場所は、独自のサービスを呼び出すmodule.run()メソッド内にあると思いますが、それは機能し、いずれにせよ短いコントローラーであるため、メインのコントローラーで行います。

7

AngularJSのバージョンに依存しているかどうかはわかりませんが、controllerプロパティに関数を提供できます。この関数は実際のコントローラーになります。この事実を controller inheritance と組み合わせて使用​​すると、探していたコードのような、より圧縮されたコードを取得できると思います。

$routeProvider
.when("/Dashboards/:dashboardName",{
    templateUrl:function(params) {
        return "Dashboards/" + params.dashboardName;
    },
    controller: function($scope, $routeParams, $controller) {
        /* this creates a child controller which, 
           if served as it is, should accomplish 
           your goal behaving as the actual controller
           (params.dashboardName + "Controller") */
        $controller($routeParams.dashboardName + "Controller", {$scope:$scope});
    }
})

免責事項:このアプローチに欠点があるかどうかは正直わかりません。しかし、そうではありません。

4
mettjus

私はこれと同じことを試みています。私が見つけた1つの解決策は、これをrouteProvider内で行うことです。

 $routeProvider
    .when("/Dashboards/:dashboardName",{
        templateUrl:function(params) {
            return "Dashboards/" + params.dashboardName;
        },
        controller: 'dynamicController'
 });

次に、「dynamicController」定義内にロードする「疑似コントローラー」(より良い名前がないため)を計算します。

var controllers = {
    unoController: function($scope, $routeParams, $rootScope) {
        // Do whatever
    },
    dosController: function($scope, $routeParams, $rootScope) {
        // Whatever for this controller
    }
}

app.controller('dynamicController', ['$scope', '$routeParams', '$rootScope', function($scope, $routeParams, $rootScope) {
    controllers[$routeParams.dashboardName+"Controller"]($scope, $routeParams, $rootScope);
}]);

これは、$ routeParams.dashboardNameが["uno"、 "dos"]のいずれかであることを前提としています。

私はAngularで約3日間しか過ごしていないので、これを一粒の塩と一緒に服用してください。

4
Benjamin Oman

これも機能するものです(少なくとも私にとって)。これは、答えを探している将来の人々を助けるかもしれません。

$stateProvider
    .state('foo', {
        url: '/foo/:bar',
        templateUrl: 'some-template-path.html',
        resolve : {
            getController : function($stateParams){
                if ($stateParams.bar === "tab1") {

                    return "tab1Controller"

                }else if ($stateParams.bar === "tab2") {

                    return "tab2Controller"

                }else if ($stateParams.bar === "tab3"){

                    return "tab3Controller"

                }else if ($stateParams.bar === "tab4") {

                    return "tab4Controller"

                }
            }
        },
        controllerProvider: function(getController){
            return getController;
        },

最短のコードではありませんが、少なくとも読みやすくなっています。また、controllerにtab/dashboardName名とは異なる名前を付けたい場合。

0
CENT1PEDE