Bagaimana cara mengirim dan mengambil parameter menggunakan $ state.go toParams dan $ stateParams?


123

Saya menggunakan AngularJS v1.2.0-rc.2 dengan ui-router v0.2.0. Saya ingin meneruskan status perujuk ke status lain jadi saya menggunakan toParamsdari $state.goseperti:

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

Menurut dokumen , ini harus mengisi $stateParamspada toStatepengontrol, tetapi memang begitu undefined. Apa yang saya lewatkan?

Saya telah membuat plunk untuk didemonstrasikan:

http://plnkr.co/edit/ywEcG1

Jawaban:


147

Jika Anda ingin meneruskan status non-URL, maka Anda tidak boleh menggunakan urlsaat menyiapkan state. Saya menemukan jawabannya di sebuah PR dan melakukan beberapa kera untuk lebih memahami.

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

Kemudian Anda dapat menavigasi ke sana seperti ini:

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

Atau:

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

Dan dalam HTML demikian:

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

Kasus penggunaan ini benar-benar terungkap dalam dokumentasi, tetapi menurut saya ini adalah cara yang ampuh untuk melakukan transisi status tanpa menggunakan URL.


2
CATATAN: (di v0.2.10) Jika statusnya adalah status anak dari induk yang memiliki parameter URL, maka parameter itu perlu disertakan dalam paramslarik.
ivarni

5
Saya mendapatkan pesan kesalahan yang mengatakan "Parameter yang diperlukan tidak ada" ketika saya mencantumkan parameter sebagai array dalam definisi status. Sebaliknya, daftarkan mereka sebagai hash seperti{referer: true, param2: true, etc: true}
Dave Ceddia

1
Ini tidak berhasil untuk saya di v0.2.13 terbaru. Mungkin, itu tidak berdokumen karena suatu alasan.
demisx

1
Terbaru, Anda perlu mengubah parameter menjadi objek. jadi params: {myParam: {value: defaultValue / undefined }}
rbnzdave

2
bagaimana saya bisa mendapatkan data di pengontrol?
Shylendra Madda

47

Solusi Nathan Matthews tidak berhasil untuk saya, tetapi sepenuhnya benar tetapi ada sedikit gunanya mencapai solusi:

Poin utamanya adalah: Jenis parameter yang ditentukan dan toParamas dari $ state.go harus berupa larik atau objek yang sama di kedua sisi transisi status.

Misalnya ketika Anda mendefinisikan params dalam keadaan sebagai berikut, Anda berarti params adalah larik karena menggunakan "[]":

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

Jadi Anda juga harus meneruskan toParams sebagai array seperti ini:

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

Dan Anda dapat mengaksesnya melalui $ stateParams sebagai array seperti ini:

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

Solusi yang lebih baik adalah menggunakan objek daripada array di kedua sisi :

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

Saya mengganti [] dengan {} dalam definisi params. Untuk meneruskan toParams ke $ state.go juga Anda harus menggunakan objek daripada array:

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

maka Anda dapat mengaksesnya melalui $ stateParams dengan mudah:

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

Pasti itu berhasil dan saya telah menggunakannya dalam proyek saya. Apakah Anda mengujinya? Beri tahu saya masalahnya, jika Anda mengujinya.
Reza Rahimi

1
itu bukan format objek {'index', 'anotherKey'} bagaimana ini bisa bekerja? Saya sudah mencobanya. Tidak berhasil.
maxisam

Letakkan cuplikan kode, versi, atau sesuatu yang dapat membantu memecahkan masalah. Saya telah menggunakan versi ini: AngularJS v1.2.26, ui-router v0.2.11, CoffeeScript juga saya telah menggunakan versi bower dari mereka.
Reza Rahimi

3
ini berfungsi, namun menggantinya params: {'index', 'anotherKey'},dengan yang params: {'index' : 'dummy', 'anotherKey' : 'dummy'},lain itu bukan objek javascript yang valid
ps0604

28

Yang harus saya lakukan adalah menambahkan parameter ke definisi status url seperti itu

url: '/toState?referer'

Doh!


Satu-satunya cara saya bisa mendapatkan ini untuk bekerja dengan /toState/:referersintaks adalah dengan menggunakan $location.path()bukan $state.go().
tayang

Anda tidak menemukan solusi lain menggunakan fungsionalitas ui-router?
Jason

ada cara untuk membuatnya bekerja dengan $ state.go (). Perlu waktu untuk melakukannya dengan benar. Lihat contoh saya di sini.
mbokil

Berhasil. Namun mungkin tidak jelas bagaimana jika Anda ingin melewatkan dua parameter; jadi baris berikut melakukan triknya. url: "/ contacts? myParam1 & myParam2"
eduardo92

15

Tidak yakin apakah ini akan bekerja dengan AngularJS v1.2.0-rc.2 dengan ui-router v0.2.0. Saya telah menguji solusi ini di AngularJS v1.3.14 dengan ui-router v0.2.13.

Saya baru menyadari bahwa tidak perlu meneruskan parameter di URL seperti yang direkomendasikan gwhn.

Cukup tambahkan parameter Anda dengan nilai default pada definisi negara Anda. Negara bagian Anda masih dapat memiliki nilai Url.

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

dan tambahkan parameter ke $state.go()

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

Seperti yang didokumentasikan di sini: Menggunakan Parameter tanpa Menentukannya di URL
Status

Coll ... Anda menyelamatkan hari saya! Solusi sederhana dan langsung.
Nowdeen

15

Tak satu pun dari contoh di halaman ini yang berhasil untuk saya. Ini yang saya gunakan dan berhasil dengan baik. Beberapa solusi mengatakan Anda tidak dapat menggabungkan url dengan $ state.go () tetapi ini tidak benar. Hal yang canggung adalah Anda harus menentukan params untuk url dan juga daftar params. Keduanya harus hadir. Diuji pada Angular 1.4.8 dan UI Router 0.2.15.

Di negara bagian, tambahkan parameter Anda ke akhir status dan tentukan params:

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

Di pengontrol Anda, pernyataan go Anda akan terlihat seperti ini:

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

Kemudian untuk mengeluarkan params dan menggunakannya di pengontrol status baru Anda (jangan lupa untuk meneruskan $ stateParams ke fungsi pengontrol Anda):

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

11

Dalam kasus saya, saya mencoba dengan semua opsi yang diberikan di sini, tetapi tidak ada yang bekerja dengan baik (angular 1.3.13, ionic 1.0.0, angular-ui-router 0.2.13). Solusinya adalah:

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

dan di state.go:

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

Bersulang


Ini berfungsi dengan baik untuk saya, asalkan controller menghormati param dengan nama yang sama, jadi $ stateParams.param1 misalnya.
nuander

ya @nuander, saya lupa menyebutkan tentang cara mengakses variabel itu, terima kasih untuk itu!
Cris R

8

Saya telah menghabiskan banyak waktu untuk bertarung dengan Ionic / Angular's $ state & $ stateParams;

Untuk memanfaatkan $ state.go () dan $ stateParams Anda harus memiliki pengaturan tertentu dan parameter lain tidak boleh ada.

Di app.config () saya, saya telah menyertakan $ stateProvider dan mendefinisikan di dalamnya beberapa status:

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

The paramskey sangat penting. Selain itu, perhatikan TIDAK ADA urlkunci yang ada ... menggunakan stateParams dan URL TIDAK bercampur. Mereka saling eksklusif satu sama lain.

Dalam panggilan $ state.go (), definisikan seperti ini:

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

The indexdan anotherKeyvariabel $ stateParams akan HANYA diisi jika mereka pertama tercantum dalam $ stateControllerparams mendefinisikan kunci.

Di dalam pengontrol, sertakan $ stateParams seperti yang diilustrasikan:

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

Variabel yang dilewati harus tersedia!


Bisakah nilainya menjadi objek JSON? Seperti $ state.go ('view', {'editObj': {val1: 2, val2: 3, val4: 'Hello'}}). Karena ini tidak berhasil untukku.
PavanSandeep

6

Coba Dengan reload: true?

Tidak tahu apa yang terjadi paling lama - ternyata saya membodohi diri sendiri. Jika Anda yakin bahwa segala sesuatunya ditulis dengan benar dan Anda akan menggunakan status yang sama, coba reload: true:

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

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

Semoga ini menghemat waktu Anda!


5

Saya pernah menghadapi masalah serupa. Saya berakhir dengan solusi yang berfungsi setelah banyak googling dan uji coba. Inilah solusi saya yang akan berhasil untuk Anda.

Saya memiliki dua pengontrol - searchBoxController dan stateResultController dan parameter bernama searchQuery untuk diteruskan dari tampilan yang memiliki kotak pencarian ke tampilan yang menunjukkan hasil yang diambil dari server jarak jauh. Beginilah cara Anda melakukannya:

Di bawah ini adalah pengontrol yang Anda gunakan untuk memanggil tampilan berikutnya $state.go()

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

Di bawah ini adalah status yang akan dipanggil saat $state.go()dieksekusi:

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

Dan terakhir, pengontrol yang terkait dengan app.searchResultsstatus:

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

1
Ini bekerja untuk saya dan itulah yang saya butuhkan, karena saya tidak ingin meneruskan parameter di URL tetapi membutuhkan properti url di pernyataan negara bagian.
Ernani

3

Dan dalam kasus saya tentang status orang tua / anak. semua parameter yang dideklarasikan dalam status anak harus diketahui oleh status induk

        .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

Solusi yang kami miliki untuk memiliki status yang membutuhkan 2 parameter berubah:

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

untuk

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

1

Anda mendefinisikan berikut di router.js

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

Pengontrol Anda perlu menambahkan $ stateParams.

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

Anda dapat mengirim objek dengan parameter sebagai berikut.

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

1

Saya mencoba Menavigasi dari Halaman 1 ke 2, dan saya harus meneruskan beberapa data juga.

Di router.js saya , saya menambahkan nama dan usia params :

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

Di Page1 , onClick dari tombol berikutnya:

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

Di Halaman2 , saya dapat mengakses parameter tersebut:

$stateParams.name
$stateParams.age

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.