จะส่งและดึงข้อมูลพารามิเตอร์โดยใช้ $ 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

คำตอบ:


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 ดังนั้น:

<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}
Dave Ceddia

1
สิ่งนี้ไม่ได้ผลสำหรับฉันใน v0.2.13 ล่าสุด บางทีมันไม่มีเอกสารด้วยเหตุผล
demisx

1
อย่างล่าสุดคุณต้องเปลี่ยนพารามิเตอร์เป็นวัตถุ พารามิเตอร์
rbnzdave

2
ฉันจะรับข้อมูลในคอนโทรลเลอร์ได้อย่างไร
Shylendra Madda

47

วิธีแก้ปัญหาของ Nathan Matthews ไม่ได้ผลสำหรับฉัน แต่มันถูกต้องโดยสิ้นเชิง แต่มีจุดเล็ก ๆ น้อย ๆ ที่จะบรรลุวิธีแก้ปัญหา:

ประเด็นสำคัญคือประเภทของพารามิเตอร์ที่กำหนดและ 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'
})

ฉันแทนที่ [] ด้วย {} ในนิยามพารามิเตอร์ สำหรับการส่ง toParams ไปยัง $ state.go คุณควรใช้ object แทน array:

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

ใช้งานได้แน่นอนและฉันได้ใช้มันในโครงการของฉัน คุณได้ทดสอบหรือไม่? แจ้งให้เราทราบปัญหาหากคุณทดสอบ
Reza Rahimi

1
ไม่ใช่รูปแบบออบเจ็กต์ {'index', 'anotherKey'} วิธีนี้ใช้ได้อย่างไร ฉันไม่ได้ลอง มันไม่ได้ผล
maxisam

ใส่ข้อมูลโค้ดเวอร์ชันหรือสิ่งที่สามารถช่วยแก้ปัญหาได้ ฉันใช้เวอร์ชันเหล่านี้แล้ว: AngularJS v1.2.26, ui-router v0.2.11, CoffeeScript ฉันยังใช้เวอร์ชันของ bower ด้วย
Reza Rahimi

3
วิธีนี้ใช้งานได้ แต่แทนที่params: {'index', 'anotherKey'},ด้วยparams: {'index' : 'dummy', 'anotherKey' : 'dummy'},อย่างอื่นไม่ใช่วัตถุจาวาสคริปต์ที่ถูกต้อง
ps0604

28

สิ่งที่ฉันต้องทำคือเพิ่มพารามิเตอร์ให้กับนิยามสถานะ url เช่นนั้น

url: '/toState?referer'

Doh!


วิธีเดียวที่ฉันจะทำให้สิ่งนี้ทำงานกับ/toState/:refererไวยากรณ์ได้คือใช้$location.path()แทน$state.go().
nshew

คุณไม่พบวิธีแก้ปัญหาอื่นใดโดยใช้ฟังก์ชันของ ui-router?
Jason

มีวิธีทำให้สิ่งนี้ทำงานกับ $ state.go () ขอเวลาหน่อยเพื่อให้ถูกต้อง ดูตัวอย่างของฉันที่นี่
mbokil

มันได้ผล อย่างไรก็ตามอาจไม่ชัดเจนว่าถ้าคุณต้องการส่งผ่านพารามิเตอร์สองตัว ดังนั้นบรรทัดต่อไปนี้จะเป็นเคล็ดลับ url: "/ contact? 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!"});


คอล ... คุณช่วยผู้ชายวันของฉัน! วิธีแก้ปัญหาที่ง่ายและตรงประเด็น
Nowdeen

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!

11

ในกรณีของฉันฉันลองใช้ตัวเลือกทั้งหมดที่ให้ไว้ที่นี่ แต่ไม่มีใครทำงานได้อย่างถูกต้อง (เชิงมุม 1.3.13, ไอออนิก 1.0.0, เชิงมุม-ui-router 0.2.13) วิธีแก้ปัญหาคือ:

.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 ฉันลืมพูดถึงวิธีเข้าถึงตัวแปรนั้นขอบคุณสำหรับสิ่งนั้น!
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 จะมีประชากรถ้าพวกเขามีการระบุไว้เป็นครั้งแรกใน $ stateController paramsกำหนดที่สำคัญ

ภายในคอนโทรลเลอร์ให้ใส่ $ 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

ฉันประสบปัญหาที่คล้ายกัน ฉันลงเอยด้วยวิธีแก้ปัญหาที่ใช้งานได้หลังจาก googling และทดลองใช้และทดสอบมากมาย นี่คือวิธีแก้ปัญหาของฉันที่เหมาะกับคุณ

ฉันมีตัวควบคุมสองตัวคือ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 ในการประกาศสถานะ
Ernani

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ของฉันฉันเพิ่มชื่อ params และอายุ :

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

ในPage1บนคลิกปุ่มถัดไป:

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

ในPage2ฉันสามารถเข้าถึงพารามิเตอร์เหล่านี้ได้:

$stateParams.name
$stateParams.age

0

หากเป็นพารามิเตอร์การค้นหาที่คุณต้องการส่งผ่านดังนี้: /toState?referer=current_user

คุณต้องอธิบายสถานะของคุณดังนี้:

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

แหล่งที่มา: https://github.com/angular-ui/ui-router/wiki/URL-Routing#query-parameters

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.