Как отправить и получить параметры, используя $state.go toParams и $stateParams?

Я использую AngularJS v1.2.0-rc.2 с ui-router v0.2.0. Я хочу передать состояние реферера в другое состояние, поэтому я использую toParams из $state.go вот так:

$state.go('toState', {referer: $state.current.name});

Согласно документам, это должно заполнить $stateParams на toState контроллер, но это undefined, Что мне не хватает?

Я создал планку, чтобы продемонстрировать:

http://plnkr.co/edit/ywEcG1

13 ответов

Решение

Все, что мне нужно было сделать, это добавить параметр в определение состояния URL, как это

url: '/toState?referer'

Doh!

Если вы хотите передать состояние без URL, то вы не должны использовать url при настройке вашего state, Я нашел ответ на пиаре и немного повозился, чтобы лучше понять.

$stateProvider.state('toState', {
  templateUrl:'wokka.html',
  controller:'stateController',
  params: {
    'referer': 'some default', 
    'param2': 'some default', 
    'etc': 'some default'
  }
});

Затем вы можете перейти к нему так:

$state.go('toState', { 'referer':'jimbob', 'param2':37, 'etc':'bluebell' });

Или же:

var result = { referer:'jimbob', param2:37, etc:'bluebell' };
$state.go('toState', result);

И в HTML таким образом:

<a ui-sref="toState(thingy)" class="list-group-item" ng-repeat="thingy in thingies">{{ thingy.referer }}</a>

Этот вариант использования полностью раскрыт в документации, но я думаю, что это мощное средство для перехода состояния без использования URL.

Решение Натана Мэтьюса не сработало для меня, но оно совершенно правильно, но нет смысла искать обходной путь:

Ключевой момент: Тип определенных параметров и toParamas в $state.go должны быть одинаковыми массивом или объектом с обеих сторон перехода между состояниями.

Например, когда вы определяете params в состоянии следующим образом, вы подразумеваете, что params является массивом из-за использования "[]":

$stateProvider
.state('home', {
    templateUrl: 'home',
    controller:  'homeController'
})
.state('view', {
    templateUrl: 'overview',
    params:      ['index', 'anotherKey'],
    controller:  'overviewController'
})

Также вы должны передать toParams в виде массива следующим образом:

params = { 'index': 123, 'anotherKey': 'This is a test' }
paramsArr = (val for key, val of params)
$state.go('view', paramsArr)

И вы можете получить к ним доступ через $stateParams как массив:

app.controller('overviewController', function($scope, $stateParams) {
    var index = $stateParams[0];
    var anotherKey = $stateParams[1];
});

Лучшее решение - использовать объект вместо массива с обеих сторон:

$stateProvider
.state('home', {
    templateUrl: 'home',
    controller:  'homeController'
})
.state('view', {
    templateUrl: 'overview',
    params:      {'index': null, 'anotherKey': null},
    controller:  'overviewController'
})

Я заменил [] на {} в определении параметров. Для передачи toParams в $state.go вам также следует использовать объект вместо массива:

$state.go('view', { 'index': 123, 'anotherKey': 'This is a test' })

тогда вы можете легко получить к ним доступ через $stateParams:

app.controller('overviewController', function($scope, $stateParams) {
    var index = $stateParams.index;
    var anotherKey = $stateParams.anotherKey;
});

Не уверен, что он будет работать с AngularJS v1.2.0-rc.2 с ui-router v0.2.0. Я протестировал это решение на AngularJS v1.3.14 с ui-router v0.2.13.

Я просто понимаю, что нет необходимости передавать параметр в URL, как рекомендует gwhn.

Просто добавьте ваши параметры со значением по умолчанию в вашем определении состояния. Ваше состояние все еще может иметь значение URL.

$stateProvider.state('state1', {
    url : '/url',
    templateUrl : "new.html",
    controller : 'TestController',
    params: {new_param: null}
});

и добавить параметр в $state.go()

$state.go('state1',{new_param: "Going places!"});

Ни один из этих примеров на этой странице не работал для меня. Это то, что я использовал, и это работало хорошо. В некоторых решениях сказано, что вы не можете комбинировать URL с $state.go(), но это не так. Неловко то, что вы должны определить параметры для URL, а также перечислить параметры. Оба должны присутствовать. Протестировано на Angular 1.4.8 и UI Router 0.2.15.

В состоянии добавьте свои параметры в конец состояния и определите параметры:

url: 'view?index&anotherKey',
params: {'index': null, 'anotherKey': null}

В вашем контроллере ваш оператор go будет выглядеть так:

$state.go('view', { 'index': 123, 'anotherKey': 'This is a test' });

Затем, чтобы извлечь параметры и использовать их в контроллере вашего нового состояния (не забудьте передать в $stateParams функцию вашего контроллера):

var index = $stateParams.index;
var anotherKey = $stateParams.anotherKey;
console.log(anotherKey); //it works!

В моем случае я попытался использовать все параметры, приведенные здесь, но никто не работал должным образом (angular 1.3.13, ionic 1.0.0, angular-ui-router 0.2.13). Решение было:

.state('tab.friends', {
      url: '/friends/:param1/:param2',
      views: {
        'tab-friends': {
          templateUrl: 'templates/tab-friends.html',
          controller: 'FriendsCtrl'
        }
      }
    })

и в гос.го:

$state.go('tab.friends', {param1 : val1, param2 : val2});

ура

Я потратил много времени на борьбу с $ state & $stateParams от Ionic / Angular;

Чтобы использовать $state.go() и $stateParams, вам необходимо настроить определенные параметры, а другие параметры не должны присутствовать.

В моем app.config() я включил $stateProvider и определил в нем несколько состояний:

$stateProvider
    .state('home', {
        templateUrl: 'home',
        controller:  'homeController'
    })
    .state('view', {
        templateUrl: 'overview',
        params:      ['index', 'anotherKey'],
        controller:  'overviewController'
    })

params Ключ особенно важен. Кроме того, обратите внимание, что нет url ключи присутствуют... используя StateParams и URL-адреса не смешиваются. Они взаимоисключающие друг друга.

В вызове $state.go() определите его так:

$state.go('view', { 'index': 123, 'anotherKey': 'This is a test' })

index а также anotherKey Переменные $stateParams будут заполняться ТОЛЬКО в том случае, если они впервые перечислены в $ stateController. params определяющий ключ.

Внутри контроллера включите $stateParams, как показано:

app.controller('overviewController', function($scope, $stateParams) {
    var index = $stateParams.index;
    var anotherKey = $stateParams.anotherKey;
});

Переданные переменные должны быть доступны!

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

У меня есть два контроллера - searchBoxController и stateResultController и параметр с именем searchQuery, который необходимо передать из представления, имеющего окно поиска, в представление, показывающее результаты, полученные с удаленного сервера. Вот как вы это делаете:

Ниже приведен контроллер, из которого вы вызываете следующий вид, используя $state.go()

.controller('searchBoxController', function ($scope, $state) {
        $scope.doSearch = function(){
            var searchInputRaw = $scope.searchQueryInput;
            $state.go('app.searchResults', { searchQuery: searchInput });
        }
    })

Ниже приведено состояние, которое будет вызываться, когда $state.go() исполняется:

.state('app.searchResults', 
            {
                url: '/searchResults',
                views:
                {
                    'menuContent': { templateUrl: 'templates/searchResult.html', controller: 'stateResultController' }
                },
                params: 
                {
                    'searchQuery': ''
                }
            })

И, наконец, контроллер, связанный с app.searchResults государство:

.controller('stateResultController', function ($scope, $state, $stateParams, $http) {
        $scope.searchQueryInput = $stateParams.searchQuery;
    });

Попробуйте с reload: true?

Не мог понять, что происходит дольше всего - оказывается, я обманываю себя. Если вы уверены, что все написано правильно, и вы будете использовать то же состояние, попробуйте reload: true:

.state('status.item', {
    url: '/:id',
    views: {...}
}

$state.go('status.item', { id: $scope.id }, { reload: true });

Надеюсь, это сэкономит ваше время!

И в моем случае состояние родителя / ребенка. все параметры, объявленные в дочернем состоянии, должны быть известны родительскому состоянию

        .state('full', {
            url: '/full',
            templateUrl: 'js/content/templates/FullReadView.html',
            params: { opmlFeed:null, source:null },
            controller: 'FullReadCtrl'
        })
        .state('full.readFeed', {
            url: '/readFeed',
            views: {
                'full': {
                    templateUrl: 'js/content/templates/ReadFeedView.html',
                    params: { opmlFeed:null, source:null },
                    controller: 'ReadFeedCtrl'
                }
            }
        })

Решение, к которому мы пришли, чтобы получить состояние, которое принимало 2 параметра, менялось

.state('somestate', {
  url: '/somestate',
  views: {...}
}

в

.state('somestate', {
  url: '/somestate?id=:&sub=:',
  views: {...}
}

Ваше определение следующее в router.js

$stateProvider.state('users', {
    url: '/users',
    controller: 'UsersCtrl',
    params: {
        obj: null
    }
})

Ваш контроллер должен добавить $stateParams.

function UserCtrl($stateParams) {
    console.log($stateParams);
}

Вы можете отправить объект по параметру следующим образом.

$state.go('users', {obj:yourObj});

Я пытался перейти со страницы 1 на 2, и мне также пришлось передать некоторые данные.

В моем router.js я добавил имя и возраст параметров:

.state('page2', {
          url: '/vehicle/:source',
          params: {name: null, age: null},
.................

На странице Page 1 нажмите следующую кнопку:

$state.go("page2", {name: 'Ron', age: '20'});

На странице 2 я мог получить доступ к этим параметрам:

$stateParams.name
$stateParams.age

Если это параметр запроса, который вы хотите передать следующим образом: /toState?referer=current_user

тогда вам нужно описать свое состояние так:

$stateProvider.state('toState', {
  url:'toState?referer',
  views:{'...'}
});

источник: https://github.com/angular-ui/ui-router/wiki/URL-Routing

Другие вопросы по тегам