Подтвердить что ты не робот

AngularJS UI Router $Состояние перезагрузки только для детей

Я использую 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, но я не нашел ничего подобного, как то, что я пытаюсь сделать. Когда я ломаю, чтобы проверить состояние $. $Current.name - имя правильное - users.userGroups, но оно перезагружает все, а не только дочернее состояние. Любая помощь очень ценится!

4b9b3361

Ответ 1

Как описано в API Reference, мы можем использовать $state.reload:

$state.reload(состояние)

Метод, который принудительно перезагружает текущее состояние. Все решения повторно реконструированы, контроллеры переустановлены, а события перезапущены.

Параметры:

  • 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'});

Ответ 3

Я получил работу. Я использовал то, что предложил Радим, но мне пришлось добавить элемент 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 }); 

Просто FYI для любых других новичков:

после того, как я добавил url в .state, у меня возникли проблемы с моими вызовами api. Он добавлял URL-адреса методам api с URL-адресом в моем .state. Вам просто нужно быть уверенным, что в ваших api-адресах есть ведущий /:

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

Я видел и изучал довольно интересные вещи, пытаясь запутаться в этом...

Ответ 4

Я думаю, что это был бы лучший подход

<a data-ui-sref="directory.organisations.details" data-ui-sref-opts="{reload: true}">Details State</a>

Мы можем перезагрузить состояние только из HTML.

Ответ 5

$state.transitionTo("State Here", {"uniqueRequestCacheBuster": null});

Это просто перезагрузит только то дочернее состояние, которое вам нужно. а не всей иерархии состояний.