web-dev-qa-db-ja.com

AngularJS-UIルーター-プログラムで状態を追加

たとえば、モジュールの構成後にプログラムで状態を$ stateProviderに追加する方法はありますか?サービス?

この質問にさらにコンテキストを追加するために、2つのアプローチを使用できる状況があります。

  1. モジュール構成で定義された状態で強制的にリロードを試みてください。問題は、状態にreloadOnSearchfalseに設定されているため、$ state.go( 'state.name'、{new:param}、{reload:true});何も起こらない、アイデアは?

状態の定義

.state('index.resource.view', {
  url: "/:resourceName/view?pageNumber&pageSize&orderBy&search",
  templateUrl: "/resourceAdministration/views/view.html",
  controller: "resourceViewCtrl",
  reloadOnSearch: false,
})
  1. ルーティングが正常に機能するように、サービスから読み込む必要がある状態をプログラムで追加してみてください。可能であれば、最初のオプションを選択します。
53
khorvat

更新された情報については-edit-をご覧ください

通常、状態は構成フェーズ中に$stateProviderに追加されます。実行時に状態を追加する場合は、$stateProviderの周りの参照を保持する必要があります。

このコードはテストされていませんが、必要なことを行う必要があります。 runtimeStatesというサービスを作成します。ランタイムコードに挿入し、状態を追加できます。

// config-time dependencies can be injected here at .provider() declaration
myapp.provider('runtimeStates', function runtimeStates($stateProvider) {
  // runtime dependencies for the service can be injected here, at the provider.$get() function.
  this.$get = function($q, $timeout, $state) { // for example
    return { 
      addState: function(name, state) { 
        $stateProvider.state(name, state);
      }
    }
  }
});

Future Statesと呼ばれるものを I-Router Extras で実装しました。まだ存在しない状態にURLをマッピングするようなものです。また、Future Statesは、ランタイム状態のソースコードを遅延ロードする方法を示します。 ソースコード を見て、何が関係しているかを感じてください。

-edit- UI-Router 1.0+向け

UI-Router 1.0では、 StateRegistry.register および StateRegistry.deregister を使用して、実行時に状態を登録および登録解除できます。

StateRegistryにアクセスするには、 $stateRegistry として挿入するか、 $uiRouter を挿入して UIRouter.stateRegistry経由でアクセスします

UI-Router 1.0には、状態定義の遅延ロード、URLによる同期も処理する将来の状態も含まれています。

109
Chris T

クリスTはそれを打ちました!プロバイダーがその道です。ウィンドウオブジェクト、セーバー、より保護されたものなどに叩く必要はありません。

この記事で彼の答えを相互参照することは本当に助けになりました: http://blog.xebia.com/2013/09/01/differences-between-providers-in-angularjs/#provider

このソリューションは、構成ブロック中の特定のモジュール$ stateProviderを、実行ブロック中に他のモジュールからアクセス可能にします。

私の状況では、ユーザーの権限に応じてダッシュボードの状態を動的に生成しています。

構成ブロック中に、プロバイダーが設定され、モジュールのstateProvider(後でアクセスされる)を渡します。

//in dashboard.module.js

var dashboardModule = angular.module('app.modules.dashboard',[
        'app.modules.dashboard.controllers',
        'app.modules.dashboard.services',
        'app.modules.dashboard.presentations.mileage'
    ])

    .provider('$dashboardState', function($stateProvider){
        this.$get = function(PATHS, $state){
            return {
                addState: function(title, controllerAs, templatePrefix) {
                    $stateProvider.state('dashboard.' + title, {
                        url: '/' + title,
                        views: {
                            'dashboardModule@dashboard': {
                                templateUrl: PATHS.DASHBOARD + (templatePrefix ? templatePrefix + '/' : '/') + title + '/' + title + '.view.html',
                                controller: controllerAs ? controllerAs : null
                            }
                        }
                    });
                }
            }
        }
    });

これにより、私のダッシュボードステートプロバイダーは、ウィンドウ上でスラップする代わりに、他のモジュールで使用できるようになります。

次に、ユーザーモジュールの実行ブロック(コントローラー)で、ダッシュボードの状態プロバイダーにアクセスし、状態を動的に挿入できます。

var UserControllers = angular.module('app.modules.user.controllers', [])

.controller("UserLoginController", ["$state", "$dashboardState", function($state, $dashboardState){

    $dashboardState.addState('faq', null, 'content');

    $state.go('dashboard.faq');

}]);
14
Alex Boisselle

はい、これを行うことは可能ですが、複雑なキャッシングレイヤーがあるためです。アレックス・ファインバーグは、彼のブログで解決策を文書化しています:

http://alexfeinberg.wordpress.com/2014/03/08/dynamically-populating-angular-ui-router-states-from-a-service/

記事の末尾には、stateProviderを使用して状態を作成する例が含まれています。

app.stateProvider.state(ent.lob.name.toLowerCase(), {
    url: '/' + ent.lob.name.toLowerCase(),
    controller: ent.lob.name.toLowerCase() + 'Controller',
    templateUrl: 'lobs/views/' + ent.lob.name.toLowerCase() + '.html'
});
4
Chad Robinson