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

123

Я использую 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

gwhn
источник

Ответы:

147

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

$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-адресов.

bbrown
источник
2
ПРИМЕЧАНИЕ: (в v0.2.10) Если состояние является дочерним для родительского состояния, у которого есть параметр URL, то этот параметр необходимо включить в paramsмассив.
ivarni
5
Когда я перечислял параметры как массив в определении состояния, я получал сообщение об ошибке «Отсутствует обязательный параметр». Вместо этого перечислите их как хэш{referer: true, param2: true, etc: true}
Dave Ceddia
1
У меня это не сработало в последней версии v0.2.13. Возможно, это было недокументировано.
demisx
1
В последнем случае вам нужно изменить параметры, чтобы они были объектом. поэтому params: {myParam: {value: defaultValue / undefined }}
rbnzdave
2
как я могу получить данные в контроллере?
Шилендра Мадда
47

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

Ключевой момент: Тип определенных параметров и 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;
});
Реза Рахими
источник
Определенно это работает, и я использовал его в своем проекте. Вы это тестировали? Сообщите мне о проблеме, если вы ее протестируете.
Реза Рахими
1
это не объектный формат {'index', 'anotherKey'} как это может работать? Я пробовал. Это не сработало.
maxisam 03
Добавьте фрагмент кода, версию или что-нибудь, что может помочь в решении проблемы. Я использовал эти версии: AngularJS v1.2.26, ui-router v0.2.11, CoffeeScript, также я использовал их версию bower.
Реза Рахими
3
это работает, однако замена params: {'index', 'anotherKey'},с в params: {'index' : 'dummy', 'anotherKey' : 'dummy'},противном случае это не является допустимым объектом Javascript
ps0604
28

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

url: '/toState?referer'

Doh!

gwhn
источник
Единственный способ заставить это работать с /toState/:refererсинтаксисом - использовать $location.path()вместо $state.go().
nshew
Вы не нашли другого решения, использующего функциональность ui-router?
Джейсон
есть способ заставить это работать с $ state.go (). Мне потребовалось некоторое время, чтобы понять это правильно. См. Мой пример здесь.
mbokil
Это сработало. Однако может быть неясно, что, если вы хотите передать два параметра; так что следующая строка делает свое дело. url: "/ contacts? myParam1 & myParam2"
eduardo92
15

Не уверен, будет ли он работать с 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!"});
Phyxius
источник
Колл ... Вы спасли мне день, ребята! Простое и прямое решение.
Nowdeen 01
15

Ни один из этих примеров на этой странице у меня не работал. Это то, что я использовал, и это хорошо сработало. В некоторых решениях говорилось, что вы не можете комбинировать 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!
mbokil
источник
11

В моем случае я попробовал использовать все варианты, указанные здесь, но никто не работал должным образом (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});

ура

Cris R
источник
Это сработало для меня, при условии, что контроллер уважает параметр с тем же именем, например, $ stateParams.param1.
nuander
да @nuander, я забыл упомянуть, как получить доступ к этой переменной, спасибо за это!
Cris R
8

Я потратил много времени на борьбу с $ 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 ТОЛЬКО будут заселены , если они первые перечислены в $ stateControllerparams определяющей ключ.

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

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

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

Натан Мэтьюз
источник
Может ли значение быть объектом JSON? Как $ state.go ('view', {'editObj': {val1: 2, val2: 3, val4: 'Hello'}}). Потому что это не работает для меня.
PavanSandeep
6

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

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

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

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

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

Cody
источник
5

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

У меня есть два контроллера - 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;
    });
Азарулла Шариф
источник
1
Это сработало для меня, и это было именно то, что мне было нужно, поскольку я не хотел передавать параметр в URL-адресе, но мне нужно было свойство url в объявлении состояния.
Эрнани,
3

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

        .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: {...}
}
Сет Колдуэлл
источник
1

Ваше определение в router.js

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

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

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

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

$state.go('users', {obj:yourObj});
MahmutKarali
источник
1

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

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

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

В Page1 , OnClick следующей кнопки:

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

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

$stateParams.name
$stateParams.age
Правееш П
источник