`यूआई-राउटर` $ राज्यप्रेम बनाम $ राज्य ।परम


116

साथ ui-router, इसकी सुई या तो संभव है $stateया $stateParamsएक नियंत्रक में URL में पैरामीटर के लिए उपयोग मिलता है। हालांकि, $stateParamsकेवल मापदंडों के माध्यम से एक्सेस करने वाले नियंत्रक द्वारा प्रबंधित राज्य से संबंधित मापदंडों को उजागर करता है जो इसे एक्सेस करता है, और इसके मूल राज्य, जबकि $state.paramsसभी पैरामीटर हैं, जिनमें किसी भी बच्चे के राज्यों में शामिल हैं।

निम्नलिखित कोड को देखते हुए, यदि हम URL को सीधे लोड करते हैं http://path/1/paramA/paramB, तो यह है कि नियंत्रक के लोड होने पर यह कैसे जाता है:

$stateProvider.state('a', {
     url: 'path/:id/:anotherParam/',
     controller: 'ACtrl',
  });

$stateProvider.state('a.b', {
     url: '/:yetAnotherParam',
     controller: 'ABCtrl',
  });

module.controller('ACtrl', function($stateParams, $state) {
   $state.params; // has id, anotherParam, and yetAnotherParam
   $stateParams;  // has id and anotherParam
}

module.controller('ABCtrl', function($stateParams, $state) {
   $state.params; // has id, anotherParam, and yetAnotherParam
   $stateParams;  // has id, anotherParam, and yetAnotherParam
}

सवाल यह है कि अंतर क्यों? और क्या आपके पास कब और क्यों उपयोग करना चाहिए, या उनमें से किसी एक का उपयोग करने से बचना चाहिए?


इस तरह के एक उत्कृष्ट सचित्र प्रश्न - मुझे यह बताने के लिए धन्यवाद कि मैं क्या पूछना चाह रहा था!
बजे पीटर निक्से जूल

जवाबों:


65

प्रलेखन आपके निष्कर्षों को यहाँ दोहराता है: https://github.com/angular-ui/ui-router/wiki/URL-Rout#stateparams-service

यदि मेरी स्मृति कार्य करती है, $stateParamsतो इसे मूल से बाद में पेश किया गया था $state.params, और निरंतर लेखन से बचने के लिए एक साधारण सहायक इंजेक्टर लगता है $state.params

मुझे संदेह है कि कोई सर्वोत्तम अभ्यास दिशानिर्देश हैं, लेकिन संदर्भ मेरे लिए जीतता है। यदि आप बस url में प्राप्त किए गए परमों तक पहुंच चाहते हैं, तो उपयोग करें $stateParams। यदि आप राज्य के बारे में कुछ और जटिल जानना चाहते हैं, तो उपयोग करें $state


1
मैंने अपने आप को उपयोग $state.paramsमें पाया ACtrl, क्योंकि मैं जाँच करना चाहता था कि yetAnotherParamक्या सेट है। ताकि अगर ऐसा न हो, तो मैं कुछ कर सकूं। मैं उस चीज़ के विवरण में नहीं जा रहा हूँ क्योंकि यह अपने आप में एक प्रश्न का वारंट कर सकता है। हालांकि, मुझे लगता है कि मैं एक पैरामीटर के लिए जाँच करके हैक कर सकता हूं जो कि एक बाल राज्य द्वारा प्रस्तुत किया गया है और वर्तमान स्थिति के माध्यम से मान्यता प्राप्त नहीं है $stateParams। मुझे तब से एक वैकल्पिक दृष्टिकोण मिला है।
22:27 पर 22:16

3
दरअसल, दोनों के बीच का अंतर केवल संदर्भ के मामले से अधिक है। $ StateParams url-based params को कैप्चर करता है, जो $ अवस्था उस राज्य पर विचार करता है, भले ही उसके बाल राज्य में अधिक params हों । $ state.params सभी यूआरएल + गैर-यूआरएल के आधार पैरामीटर पर कब्जा करने लगता है वर्तमान स्थिति आप में कर रहे हैं। आप राज्य में हैं, तो parent.child, फिर $stateParamsमें parentControllerकी यूआरएल आधारित पैरामीटर का मूल्यांकन करेंगे parent, लेकिन नहीं के उन parent.childइस मुद्दे को देखें ।
एमीज

1
दूसरी ओर, $ StateParams कस्टम ऑब्जेक्ट्स, प्रकारों आदि को संरक्षित कर सकते हैं, जबकि $ State.params "कस्टम ऑब्जेक्ट्स को सादे ऑब्जेक्ट्स में कनवर्ट करेंगे"।
एमीज

2
$stateParamsसमाधान में काम करता है, जबकि $state.paramsगलत है (राज्य के लिए
परमान

1
मैंने पाया कि गुंजाइश $ $ देख सकती है। मुझे कोई जानकारी नहीं है की क्यों।
weltschmerz

19

उपयोग करने का एक और कारण $state.paramsगैर-URL आधारित स्थिति के लिए है, जो (मेरे दिमाग में) बहुत कमज़ोर और बहुत शक्तिशाली है।

मैंने इसे केवल URL में उजागर किए बिना राज्य को कैसे पारित किया जाए, के बारे में गुगली करते हुए इसे खोजा और SO पर कहीं और एक प्रश्न का उत्तर दिया

मूल रूप से, यह इस प्रकार के वाक्यविन्यास की अनुमति देता है:

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

हाय bbrown, किसी तरह मैं यह काम नहीं कर सकता, क्या आपके पास एक काम करने का उदाहरण है?
तूफान_बस्टर

14

EDIT: यह उत्तर संस्करण के लिए सही है 0.2.10। जैसा @Alexander Vasilyev ने बताया कि यह संस्करण में काम नहीं करता है 0.2.14

उपयोग करने का एक अन्य कारण यह $state.paramsहै कि आपको इस तरह से क्वेरी पैरामीटर निकालने की आवश्यकता है:

$stateProvider.state('a', {
  url: 'path/:id/:anotherParam/?yetAnotherParam',
  controller: 'ACtrl',
});

module.controller('ACtrl', function($stateParams, $state) {
  $state.params; // has id, anotherParam, and yetAnotherParam
  $stateParams;  // has id and anotherParam
}

2
अब लागू नहीं है। प्लंकर देखें: plnkr.co/edit/r2JhV4PcYpKJdBCwHIWS?p=preview
अलेक्जेंडर

4

इन दोनों के बीच कई अंतर हैं। लेकिन व्यावहारिक रूप से काम करते हुए मैंने पाया है कि $state.paramsबेहतर उपयोग करना । जब आप अधिक से अधिक मापदंडों का उपयोग करते हैं तो यह बनाए रखने में भ्रमित हो सकता है $stateParams। अगर हम कई पैरामेट्स का उपयोग करते हैं जो कि URL परम नहीं हैं $stateतो बहुत उपयोगी है

 .state('shopping-request', {
      url: '/shopping-request/{cartId}',
      data: {requireLogin: true},
      params : {role: null},
      views: {
        '': {templateUrl: 'views/templates/main.tpl.html', controller: "ShoppingRequestCtrl"},
        'body@shopping-request': {templateUrl: 'views/shops/shopping-request.html'},
        'footer@shopping-request': {templateUrl: 'views/templates/footer.tpl.html'},
        'header@shopping-request': {templateUrl: 'views/templates/header.tpl.html'}
      }
    })

3

मेरी एक जड़ अवस्था है जो sth को हल करती है। $stateएक रिज़ॉल्यूशन पैरामीटर के रूप में पासिंग के लिए उपलब्धता की गारंटी नहीं होगी $state.params। लेकिन $stateParamsइच्छाशक्ति का उपयोग करना।

var rootState = {
    name: 'root',
    url: '/:stubCompanyId',
    abstract: true,
    ...
};

// case 1:
rootState.resolve = {
    authInit: ['AuthenticationService', '$state', function (AuthenticationService, $state) {
        console.log('rootState.resolve', $state.params);
        return AuthenticationService.init($state.params);
    }]
};
// output:
// rootState.resolve Object {}

// case 2:
rootState.resolve = {
    authInit: ['AuthenticationService', '$stateParams', function (AuthenticationService, $stateParams) {
        console.log('rootState.resolve', $stateParams);
        return AuthenticationService.init($stateParams);
    }]
};
// output:
// rootState.resolve Object {stubCompanyId:...}

"कोणीय" का उपयोग करना: "~ 1.4.0", "कोणीय-यूआई-राउटर": "~ 0.2.15"


2

एक राज्य से दूसरे मार्ग पर जाने के दौरान एक दिलचस्प अवलोकन जो मैंने किया, वह यह है कि $ राज्यप्रेमों को फहराया जाता है और पिछले मार्ग के राज्य परिमों को अधिलेखित कर दिया जाता है जिन्हें वर्तमान राज्य परिमों के साथ पारित किया गया था, लेकिन $state.paramएस का उपयोग नहीं किया गया।

उपयोग करते समय $stateParams:

var stateParams        = {};
stateParams.nextParams = $stateParams; //{item_id:123}
stateParams.next       = $state.current.name;

$state.go('app.login', stateParams);
//$stateParams.nextParams on app.login is now:
//{next:'app.details', nextParams:{next:'app.details'}}

$ राज्य का उपयोग करते समय।

var stateParams        = {};
stateParams.nextParams = $state.params; //{item_id:123}
stateParams.next       = $state.current.name;

$state.go('app.login', stateParams);
//$stateParams.nextParams on app.login is now:
//{next:'app.details', nextParams:{item_id:123}}

1

यहाँ इस लेख में स्पष्ट रूप से समझाया गया है: $stateसेवा राज्य में हेरफेर करने के साथ-साथ वर्तमान स्थिति पर प्रासंगिक डेटा के लिए कई उपयोगी तरीके प्रदान करती है। वर्तमान राज्य पैरामीटर $stateसेवा की परमेस कुंजी पर सुलभ हैं । $stateParamsसेवा के लिए यह बहुत ही वस्तु देता है। इसलिए, $stateParamsसेवा पर परमेस ऑब्जेक्ट को जल्दी से एक्सेस करने के लिए सेवा कड़ाई से एक सुविधा सेवा है $state

जैसे, किसी भी नियंत्रक को कभी भी $stateसेवा और उसकी सुविधा सेवा दोनों को इंजेक्ट नहीं करना चाहिए $stateParams। यदि इसे $stateकेवल वर्तमान मापदंडों तक पहुंचने के लिए इंजेक्ट किया जा रहा है, तो नियंत्रक को $stateParamsइसके बजाय इंजेक्ट करने के लिए फिर से लिखना चाहिए ।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.