Як надсилати та отримувати параметри за допомогою $ state.go toParams та $ stateParams?


123

Я використовую AngularJS v1.2.0-rc.2 з ui-роутером v0.2.0. Я хочу , щоб передати стан посилається в інший стан , так я використовую toParamsз $state.goприблизно так:

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

Згідно з документами , це має заповнити $stateParamsна toStateконтролері, але це так undefined. Що я пропускаю?

Я створив планк, щоб продемонструвати:

http://plnkr.co/edit/ywEcG1

Відповіді:


147

Якщо ви хочете передати стан без 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 timely:

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

Цей випадок використання повністю розкрито в документації, але я думаю, що це потужний засіб для переходу стану без використання URL-адрес.


2
ПРИМІТКА: (на v0.2.10) Якщо стан - це дочірній стан батьків, у якого є параметр URL, то цей параметр потрібно включити до params масиву.
ivarni

5
Я отримував помилку, кажучи "Відсутній необхідний параметр", коли я перераховував парами як масив у визначенні стану. Натомість перерахуйте їх як хеш{referer: true, param2: true, etc: true}
Дейв Седдія

1
Це не спрацювало для мене в останній версії 1.2.2. Можливо, це було недокументовано чомусь.
демікс

1
Найновіше вам потрібно змінити парами, щоб бути об’єктом. so params: {myParam: {value: defaultValue / undefined }}
rbnzdave

2
як я можу отримати дані в контролері?
Шилендра Мадда

47

Рішення Натана Меттьюса не спрацювало для мене, але воно цілком правильне, але мало сенсу досягти рішення:

Ключовим моментом є: Тип визначених параметрів і toParamas $ state.go повинен бути однаковим масивом або об'єктом з обох сторін переходу стану.

Наприклад, коли ви визначаєте парами у такому стані, значить, парами є масивом через використання "[]":

$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'
})

Я замінив [] на {} у визначенні парам. Для переходу до Парами до $ 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

Розмістіть фрагмент коду, версію або щось, що може допомогти вирішити проблему. Я використовував ці версії: 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'

До!


Єдиний спосіб, коли я можу змусити це працювати з /toState/:refererсинтаксисом, - це використовувати $location.path()замість $state.go().
nshew

Ви не знайшли жодного іншого рішення, що використовувало функціонал ui-роутера?
Джейсон

є спосіб змусити це працювати з $ state.go (). Взяв у мене трохи часу, щоб правильно це зрозуміти. Дивіться мій приклад тут.
mbokil

Це спрацювало. Однак може бути не ясно, що робити, якщо ви хочете передати два параметри; тому наступний рядок робить трюк. url: "/ контакти? myParam1 & myParam2"
eduardo92

15

Не впевнений, чи буде він працювати з AngularJS v1.2.0-rc.2 з ui-роутером v0.2.0. Я протестував це рішення на AngularJS v1.3.14 за допомогою ui-роутера 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!"});


Coll ... Ти врятував мені мій день! Просте і пряме рішення.
Nowdeen

15

Жоден із цих прикладів на цій сторінці не працював для мене. Це те, що я використав, і це добре працювало. У деяких рішеннях сказано, що ви не можете комбінувати URL-адресу з $ state.go (), але це неправда. Найзручніше - ви повинні визначити параметри для URL-адреси, а також перелічити парами. Обоє повинні бути присутніми. Тестовано на кутовому 1.4.8 та маршрутизаторі 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!

11

У моєму випадку я спробував з усіма наведеними тут варіантами, але ніхто не працював належним чином (кутовий 1.3.13, іонний 1.0.0, кутовий-маршрутизатор 0,23). Рішення було:

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

і в state.go:

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

Ура


Для мене це спрацювало чудово, за умови, що контролер шанує однойменний парам, так, наприклад, $ 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 });

Сподіваюся, це заощадить ваш час!


5

Я зіткнувся з подібною проблемою. Я закінчився робочим рішенням після багатьох гуглів та випробувань та випробувань. Ось моє рішення, яке працювало б для вас.

У мене є два контролери - 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

Рішення, з якого ми дійшли до того, що стан, який приймав 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});

1

Я намагався перейти від сторінки 1 до 2, і мені довелося також передавати деякі дані.

У свій router.js я додав ім'я парам і вік :

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

На сторінці1 натисніть наступну кнопку:

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

У Page2 , я міг би отримати доступ до цих Params:

$stateParams.name
$stateParams.age

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.