2012-12-02 9 views
14

ng-view और $routeProvider का उपयोग करते समय, /foo/:id/:user/:item जैसे पथ के मान प्राप्त करने के लिए $routeParams इंजेक्ट करना संभव है। पथ में उन पैरामीटर को सेट करने का कोई तरीका है? $routeParams.id = 3 की तरह कुछ, और उसके बाद यूआरएल में दिखाई देता है।

मुझे पता है कि यह प्रभाव $location.path() के माध्यम से हासिल किया जा सकता है, लेकिन मैं उच्च स्तर के अमूर्तता की उम्मीद कर रहा हूं जिसके लिए स्ट्रिंग मैनिपुलेशन की आवश्यकता नहीं है।

उत्तर

12

यहां बताया गया है कि मैं समस्या को हल करने में कैसे कामयाब रहा।

नियंत्रक:

app.controller('MainCtrl', [ 
    '$scope', '$log', '$route', '$routeParams', '$location', 
    function(scope, console, route, routeParams, location) { 
    console.log('MainCtrl.create'); 
    scope.route = route; 
    scope.routeParams = routeParams; 
    scope.location = location; 

    //1. This needs to be enabled for each controller that needs to watch routeParams 
    //2. I believe some encapsulation and reuse through a service might be a better way 
    //3. The reference to routeParams will not change so we need to enable deep dirty checking, hence the third parameter 

    scope.$watch('routeParams', function(newVal, oldVal) { 
     angular.forEach(newVal, function(v, k) { 
     location.search(k, v); 
     }); 
    }, true); 
    }]); 

मॉड्यूल घोषणा + मार्ग परिभाषा:

var app = angular.module('angularjs-starter', [], [ 
     '$routeProvider', '$locationProvider', 
     function(routeProvider, locationProvider) { 
     routeProvider.when('/main', { 
      template : 'Main', 
      controller : 'MainCtrl', 
      reloadOnSearch : false 
     }); 
     } ]); 

खाका:

<body ng-controller="MainCtrl"> 
    <a href="#/main">No Params</a> 
    <a href="#/main?param1=Hello&param2=World!">With Params</a> 

    <div ng-view></div> 

    <p> 
    <span>param1</span> 
    <input type="text" ng-model="routeParams['param1']"> 
    </p> 
    <p> 
    <span>param2</span> 
    <input type="text" ng-model="routeParams['param2']"> 
    </p> 

    <pre>location.path() = {{location.path()}}</pre> 
    <pre>routeParams = {{routeParams}}</pre> 
</body> 

डेमो:

संदर्भ:

1

साथ ही, आप $ साथ url पैरामीटर के लिए दो तरह से डेटा बाइंडिंग चाहते हैं स्थान, यह सी मिलन समारोह मदद करेगा।

bind_var_to_urlparam = function(variable_name, scope){ 
    // initial loading from urlparams and then 
    // set a watch function to update the urlparams on update 
    scope[variable_name] = $location.search()[variable_name]; 
    scope.$watch(variable_name, function(newVal, oldVal){ 
    var search_obj = {}; 
    search_obj[variable_name] = newVal; 
    $location.search(search_obj); 
    }); 
} 

मैं एक साझा सेवा से इस का उपयोग करें, यही कारण है कि क्षेत्र में पारित हो जाता है है

+1

मुझे यह पसंद है! नोट, हालांकि, यह वास्तव में दो-तरफा डाटाबेसिंग नहीं है। जब फ़ंक्शन को कॉल किया जाता है, तो स्कोप वैरिएबल URL param के वर्तमान मान पर सेट होता है, और उसके बाद, URL चरम को बदलता है जब स्कोप परिवर्तनीय परिवर्तन होते हैं। यदि दो स्कॉप्स एक ही यूआरएल परम से जुड़ते हैं, तो इसे बदलने वाला एक गुंजाइश दूसरे दायरे में चर को अपडेट नहीं करेगा। हालांकि यह कई उद्देश्यों के लिए पर्याप्त है। – tobek

+0

यह वही सही है, एक ही यूआरएल परम के लिए बाध्यकारी विभिन्न क्षेत्रों के बारे में अच्छा बिंदु। –

0

मैं एक सेवा का उपयोग बाध्यकारी एक दो तरह से बनाने के लिए:।

angular.module('app').service('urlBinder', ['$location', function($location) { 
    this.bindOnScope = function(scope, name, urlParamName) { 
     // update the url when the scope variable changes 
     var unhookUrlUpdater = scope.$watch(name, function(newValue, oldValue) { 
      if (!angular.equals(oldValue, newValue)) { 
       $location.search(urlParamName, newValue); 
      } 
     }); 

     // update the scope variable when the url changes 
     var unhookScopeUpdater = scope.$on('$locationChangeSuccess', function() { 
      var value = $location.search()[urlParamName]; 

      if (!angular.equals(scope[name], value)) { 
       scope[name] = value; 
      } 
     }); 

     // return a function to remove the hooks. Note that since these hooks are set up on the scope passed in, if that scope gets destroyed (e.g. because the user went to a different page and the controller is no longer present), then the hooks will be removed automatically. 
     return function() { 
      unhookUrlUpdater(); 
      unhookScopeUpdater(); 
     }; 
    }; 

    // the same thing but using getter/setter functions for when you want to bind to something not on the scope 
    this.bind = function(scope, getter, setter, urlParamName) { 
     var unhookUrlUpdater = scope.$watch(getter, function(newValue) { 
      $location.search(urlParamName, newValue); 
     }); 

     var unhookScopeUpdater = scope.$on('$locationChangeSuccess', function() { 
      var value = $location.search()[urlParamName]; 

      if (!angular.equals(getter(), value)) { 
       setter(value); 
      } 
     }); 

     return function() { 
      unhookUrlUpdater(); 
      unhookScopeUpdater(); 
     }; 
    }; 
}]); 

अपने नियंत्रक में:

angular.module('app').controller('ctrl', ['$scope', function($scope) { 
    // if binding to something on the scope: 
    urlBinder.bindToScope($scope, 'something', 'url-name'); 
    $scope.something = 'test'; 

    // or if the variable you want to bind isn't on the scope: 
    var someVariable; 
    urlBinder.bind(
     $scope, 
     function() { return someVariable; }, 
     function(value) { someVariable = value; }, 
     'url-name'); 
}]); 

फिर आप उदाहरण के लिए यूआरएल के लिए एक इनपुट बाध्य कर सकते हैं:

<div ng-controller="ctrl"> 
    <input type="number" ng-model="something" /> 
</div> 

तुम भी रूप में आप नियंत्रक गुंजाइश नष्ट हो नहीं करना चाहती और निर्मित, अपने मार्ग config में reloadOnSearch : false स्थापित करने के लिए आवश्यकता हो सकती है जब भी यूआरएल परिवर्तन की खोज बिट।

संबंधित मुद्दे