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

gwhn
sumber

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.

bbrown
sumber
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;
});
Reza Rahimi
sumber
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!

gwhn
sumber
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!"});
Phyxius
sumber
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!
mbokil.dll
sumber
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

Cris R
sumber
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!

Nathan Matthews
sumber
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!

Cody
sumber
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;
    });
Azharullah Shariff
sumber
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'
                }
            }
        })
zinking
sumber
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: {...}
}
Seth Caldwell
sumber
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});
Mahmut Karali
sumber
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
Praveesh P
sumber