web-dev-qa-db-ja.com

AngularJS UI Router $ stateは、子の状態のみをリロードします

メインメニューのタブと、いずれかの状態(ユーザー)内のリンクにUIルーターを使用しています。ユーザー状態にはユーザーのリストがあり、ユーザーがクリックされると、子状態のみをリロードしますが、子状態と親状態(ユーザー)の両方をリロードします。

ここに私のコードがあります:

    app.config(function ($stateProvider, $locationProvider, $urlRouterProvider) {
    $urlRouterProvider.otherwise("/");
    $locationProvider.html5Mode(true);
    $stateProvider
        .state('home', {
            abstract: true,
            template: '<div ui-view=""></div>',
            controller: 'HomeController as homeCtrl'
        })
        .state('users', {
            parent: 'home',
            url: '/users',
            templateUrl: '/User/Index',
            controller: 'UserController as userCtrl',
        })
        .state('users.createUser', {
            templateUrl: '/User/CreateUser',
            controller: 'CreateUserController as cuCtrl'
        })
        .state('users.editUser', {
            templateUrl: '/User/EditUser',
            controller: 'EditUserController as euCtrl',
            resolve: {
                userInfo: function (contextInfo, userData) {
                    return userData.get(contextInfo.getUserKey());
                }
            }
        })
        .state('users.addWebItemsForUser', {
            templateUrl: '/User/AddWebItemsForUser',
            controller: 'UserWebItemsController as uwiCtrl'
        })
        .state('users.addReportsForUser', {
            templateUrl: '/User/AddReportsForUser',
            controller: 'UserReportsController as urCtrl'
        })
        .state('users.userGroups', {
            templateUrl: '/User/UserGroups',
            controller: 'UserGroupController as userGroupCtrl'
        })
        //.state('users.logInWebApp', {
        //    template: '<h3>Logging into web app</h3>',
        //    resolve: {
        //        user: function() {
        //            return {
        //                //companyId: contextInfo.getCustomerKey()
        //                //userId:
        //                //password:
        //            }
        //        }
        //    },
        //    controller: function() {
        //        // need company code, username and password of user then need to open window with webapp url (will that work?) - do we still want to add this functionality?
        //    }
        //})
        .state('links', {
            url: '/links',
            templateUrl: '/Link/Index',
            controller: 'LinkController as linkCtrl'
        })
        .state('onlrpts', {
            url: '/onlineReports',
            templateUrl: '/OnlineReport/Index',
            controller: 'OnlineReportController as onlRptCtrl'
        })
        .state('reports', {
            url: '/customerReports',
            templateUrl: '/CustomerReport/Index',
            controller: 'CustomerReportController as custRptCtrl'
        });
})
.config(function($provide) {
    $provide.decorator('$state', function($delegate, $stateParams) {
        $delegate.forceReload = function() {
            return $delegate.go($delegate.$current.name, $stateParams, {
                reload: true,
                inherit: false,
                notify: true
            });
        };
        return $delegate;
    });
});

これは、ユーザーがクリックされたときに呼び出される親コントローラー(UserController)の関数です。

            this.userTreeClick = function(e) {
        contextInfo.setUserKey(e.Key);
        contextInfo.setUserName(e.Value);
        userCtrl.userKey = e.Key;
        $state.forceReload();
    };

したがって、私がusers.userGroups状態にあったとしましょう。別のユーザーをクリックすると、users.userGroups状態のみがリロードされます。これは可能ですか? GoogleとここStackOverflowで答えを探しましたが、私がやろうとしていることとまったく同じようなものは見つかりませんでした。 $ state。$ current.name-名前が正しい-users.userGroupsを確認するために中断すると、子状態だけでなくすべてをリロードします。どんな助けも大歓迎です!

29
dfstewart3

APIリファレンスに記載されているように、_$state.reload_を使用できます。

$ state.reload(state)

現在の状態を強制的にリロードするメソッド。すべての解決が再解決され、コントローラーが再インスタンス化され、イベントが再起動されます。

パラメーター:

  • state(オプション)
    • 状態名または状態オブジェクト。これは、再解決される解決のルートです。

例:

_//will reload 'contact.detail' and 'contact.detail.item' states
$state.reload('contact.detail');
_

同様に、$state.go()とそのoptionsパラメーターで達成できます:

$ state.go(to、params、options)

...

  • options(オプション)
    • location ...
    • inherit ...
    • relative ...
    • notify ...
    • reload(v0.2.5)-{boolean = false | string | object}、trueの場合、状態やパラメーターが変更されていなくても強制的に遷移します。現在の状態と親状態の解決とビューをリロードします。 reloadが文字列(または状態オブジェクト)の場合、状態オブジェクトは(名前またはオブジェクト参照によって)フェッチされます。そして\遷移は、その一致した状態とそのすべての子状態の解決とビューを再読み込みします。

https://github.com/angular-ui/ui-router/issues/1612#issuecomment-77757224 の例:Chris T:

_{ reload: true } // reloads all,
{ reload: 'foo.bar' } // reloads top.bar, and any children
{ reload: stateObj } // reloads state found in stateObj, and any children
_

_$state.go('contact', {...}, {reload: 'contact.detail'});
_
30
Radim Köhler

動作するようになりました。 Radimが提案したものを使用しましたが、状態にurl要素を追加する必要がありました。

.state('users.userGroups', {
    url: '/userGroups/{userTrigger}',
    templateUrl: '/User/UserGroups',
    controller: 'UserGroupController as userGroupCtrl'
})

私のコントローラーでは、ユーザーがリンクをクリックすると、$state.transitionToを使用します。

var params = angular.copy($state.params);
params.userTrigger = params.userTrigger === null ? "" : null;
$state.transitionTo($state.current, params, { reload: false, inherit: true, notify: true }); 

そこにいる他の初心者のためのちょうど参考:

url.stateに追加した後、API呼び出しで問題が発生し始めました。 .stateのURLを使用して、APIメソッドの前にURLを追加していました。 API URLに先頭の/が含まれていることを確認する必要があります。

.factory('usersInGroup', function($http) {
    return {
        get: function(groupName) {
            return $http.get('/api/UserApi/GetInGroup/' + groupName);
        }
    }

私はこれをいじろうとしてかなり興味深いものを見たし、学んだ...

1
dfstewart3