AngularJS डायनेमिक रूटिंग


88

वर्तमान में मेरे पास एक AngularJS एप्लिकेशन है जिसमें राउटिंग बिल्ट इन है। यह काम करता है और सब कुछ ठीक है।

मेरी app.js फ़ाइल इस तरह दिखती है:

angular.module('myapp', ['myapp.filters', 'myapp.services', 'myapp.directives']).
  config(['$routeProvider', function ($routeProvider) {
      $routeProvider.when('/', { templateUrl: '/pages/home.html', controller: HomeController });
      $routeProvider.when('/about', { templateUrl: '/pages/about.html', controller: AboutController });
      $routeProvider.when('/privacy', { templateUrl: '/pages/privacy.html', controller: AboutController });
      $routeProvider.when('/terms', { templateUrl: '/pages/terms.html', controller: AboutController });
      $routeProvider.otherwise({ redirectTo: '/' });
  }]);

मेरे ऐप में एक CMS बनाया गया है जहाँ आप / html निर्देशिका के भीतर नई html फाइलें कॉपी और जोड़ सकते हैं ।

मैं अभी भी रूटिंग प्रदाता के माध्यम से जाना चाहूंगा, हालांकि नई गतिशील रूप से जोड़ी गई फ़ाइलों के लिए भी।

एक आदर्श दुनिया में रूटिंग पैटर्न होगा:

$ मार्गप्रोपिडर.वन ('/ pagename ', {templateUrl: '/ Pages / pagename .html', कंट्रोलर: CMSController});

इसलिए यदि मेरा नया पृष्ठ नाम "contact.html" है, तो मैं कोणीय "लाइक" / संपर्क "और" /pages/contact.html "पर पुनर्निर्देशित करना चाहूंगा।

यह भी संभव है ?! और यदि ऐसा है तो कैसे ?!

अपडेट करें

अब मेरे पास मेरे रूटिंग कॉन्फिग में यह है:

$routeProvider.when('/page/:name', { templateUrl: '/pages/home.html', controller: CMSController })

और मेरे सीएमएसकंट्रोलर में:

function CMSController($scope, $route, $routeParams) {
    $route.current.templateUrl = '/pages/' + $routeParams.name + ".html";
    alert($route.current.templateUrl);
}
CMSController.$inject = ['$scope', '$route', '$routeParams'];

यह वर्तमान टेम्प्लेट को सही मान पर सेट करता है।

हालाँकि मैं अब नए टेम्पलेटउपयोग मूल्य के साथ एनजी-व्यू बदलना चाहूंगा । यह कैसे पूरा किया जाता है?

जवाबों:


132
angular.module('myapp', ['myapp.filters', 'myapp.services', 'myapp.directives']).
        config(['$routeProvider', function($routeProvider) {
        $routeProvider.when('/page/:name*', {
            templateUrl: function(urlattr){
                return '/pages/' + urlattr.name + '.html';
            },
            controller: 'CMSController'
        });
    }
]);
  • जोड़ना * आप गतिशील रूप से निर्देशिकाओं के कई स्तरों के साथ काम करते हैं । उदाहरण: / पृष्ठ / कारें / बिक्री / सूची इस प्रदाता पर पकड़ की जाएगी

डॉक्स से (1.3.0):

"यदि टेम्पलेटव्यू एक फ़ंक्शन है, तो इसे निम्नलिखित मापदंडों के साथ बुलाया जाएगा:

{Array।} - मौजूदा $ लोकेशन से निकाले गए रूट पैरामीटर (मौजूदा रूट को लागू करके) (")

भी

जब (पथ, मार्ग): विधि

  • पथ में एक बृहदान्त्र के साथ शुरू होने और एक तारे के साथ समाप्त होने वाले नाम समूह हो सकते हैं: उदा: नाम *। मार्ग से मेल खाने पर दिए गए नाम के तहत सभी वर्ण $ मार्गप्रेम में उत्सुकता से संग्रहीत होते हैं।

5
समय के साथ आगे बढ़ने की आवश्यकता है ... मैंने जो कार्यक्षमता बनाई थी वह v1.0.2 में गायब थी अब उपलब्ध है। इस उत्तर के लिए स्वीकृत उत्तर को अद्यतन करना
ग्रेग

सच कहूं तो मुझे यह मौजूदा 1.3 बेटों
आर्किमिडीज़ ट्रैजानो जूल

वास्तव में यह काम कर रहा है जब मैंने ऐसा किया था ... जब ('/' पेज ', {templateUrl: फ़ंक्शन (पैरामीटर) {वापसी पैरामीटर्स। पेज +' .html ';};
आर्किमिडीज ट्रेजानो

गंभीरता से .. यह वास्तव में बेवकूफ़ है कि कोणीय के पास एक डिफ़ॉल्ट व्यवहार के रूप में नहीं है ... यह मैनुअल रूटिंग हास्यास्पद है
गुइलेर्मे फेरेरा

3
कृपया समझाएं, कहां से urlattrसेट या भेजा गया है, मेरा मतलब है कि क्या urlattr.nameउत्पादन होगा?
सामी

37

ठीक है हल कर दिया।

GitHub में समाधान जोड़ा गया - http://gregorypratt.github.com/AngularDynamicRouting

मेरे app.js रूटिंग कॉन्फिग में:

$routeProvider.when('/pages/:name', {
    templateUrl: '/pages/home.html', 
    controller: CMSController 
});

फिर मेरे सीएमएस नियंत्रक में:

function CMSController($scope, $route, $routeParams) {

    $route.current.templateUrl = '/pages/' + $routeParams.name + ".html";

    $.get($route.current.templateUrl, function (data) {
        $scope.$apply(function () {
            $('#views').html($compile(data)($scope));
        });
    });
    ...
}
CMSController.$inject = ['$scope', '$route', '$routeParams'];

# साक्षात्कार मेरा होने के साथ <div id="views" ng-view></div>

तो अब यह मानक मार्ग और गतिशील मार्ग के साथ काम करता है।

इसे जांचने के लिए मैंने इसे कॉपी किया। html ने इसे पोर्टफोलियो डॉट कॉम कहा। इसमें से कुछ को सामग्री में बदल दिया और /#/pages/portfolioमेरे ब्राउज़र में प्रवेश किया और हे प्रिस्टो पोर्टफोलियो को प्रदर्शित किया गया।

अद्यतित $ $ लागू और HTML में $ संकलन करता है ताकि गतिशील सामग्री को इंजेक्ट किया जा सके।


2
यह केवल स्थैतिक सामग्री के साथ काम करता है, अगर मैं इसे सही ढंग से समझता हूं। इसका कारण यह है कि आप jQuery (कोणीय के दायरे से बाहर) के माध्यम से नियंत्रक को त्वरित करने के बाद डोम को बदल रहे हैं। चर {{यह}} की तरह काम कर सकते हैं (मैं इसे करने की कोशिश करनी होगी), लेकिन सबसे अधिक संभावना निर्देश नहीं होगा। इस बारे में सावधान रहें, क्योंकि यह अब उपयोगी हो सकता है, लेकिन बाद में कोड को तोड़ सकता है ..
टियागो रोल्डो

यह सच है कि बाध्यकारी काम नहीं करता है, मेरे लिए हालांकि मैं बहुत अधिक उपद्रव नहीं कर रहा हूं क्योंकि मैं चाहता हूं कि ग्राहक केवल नए पृष्ठ जोड़ने में सक्षम हों। मेरे द्वारा जोड़े गए किसी भी पृष्ठ को मार्ग विन्यास के माध्यम से उचित रूप से निर्दिष्ट किया जाएगा। हालांकि अच्छी बात है।
ग्रेग

1
यदि आप स्थिर HTML सामग्री रेंडर करना चाहते हैं तो यह एक बुरा समाधान नहीं है। जब तक आप ध्यान में रखते हैं कि आप अनिवार्य रूप से एनजी-व्यू को स्टैटिक (गैर कोणीय) सामग्री के साथ ओवरराइड कर रहे हैं। इसे ध्यान में रखते हुए, यह दोनों को अलग करने के लिए क्लीनर होगा, जिससे <div id = "user-views"> </ div> एलिमेंट जैसा कुछ बनता है, और वहां आपका "यूजर टेम्प्लेट" इंजेक्ट होता है। इसके अलावा, $ path.current.templateUrl को ओवरराइड करने में बिलकुल भी कोई समझदारी नहीं है - एक $ स्कोप बना ।userTemplate मॉडल और $ ('# उपयोगकर्ता-विचार') कर रहा है। लोड ($ स्कोप ।userTemplate) क्लीनर है, और कोणीय में से कोई भी नहीं तोड़ता है। कोड।
टियागो रोल्डो

1
नहीं - एनजी-व्यू निर्देश बल्कि सीमित है - या बेहतर कहा गया है, यह देशी मार्ग प्रणाली के साथ उपयोग के लिए विशिष्ट है (जो बदले में, अभी भी सीमित है, इहो)। जैसा कि आपने कहा था, सामग्री को DOM तत्व में इंजेक्ट कर सकते हैं, और फिर संरचना को फिर से बनाने के लिए कोणीय बताने के लिए $ संकलन विधि को कॉल कर सकते हैं। यह किसी भी बाइंडिंग को ट्रिगर करेगा जिसकी आवश्यकता है।
टिआगो रोल्डो

2
काम करता है, लेकिन आपको अपने नियंत्रक में डोम हेरफेर नहीं करना चाहिए।
dmackerman

16

मुझे लगता है कि इस तरह का काम करने का सबसे आसान तरीका मार्गों को बाद में हल करना है, आप उदाहरण के लिए, जोसन के माध्यम से मार्गों को पूछ सकते हैं। जाँच करें कि मैं $ फ़ैक्टरी के माध्यम से $ मार्गप्रोविडर से बाहर एक फैक्ट्री बनाता हूँ, $ प्रदान के माध्यम से, इसलिए मैं रन फ़ेज़ में $ मार्गप्रोविडर ऑब्जेक्ट का उपयोग कर सकता हूं, और नियंत्रकों में भी।

'use strict';

angular.module('myapp', []).config(function($provide, $routeProvider) {
    $provide.factory('$routeProvider', function () {
        return $routeProvider;
    });
}).run(function($routeProvider, $http) {
    $routeProvider.when('/', {
        templateUrl: 'views/main.html',
        controller: 'MainCtrl'
    }).otherwise({
        redirectTo: '/'
    });

    $http.get('/dynamic-routes.json').success(function(data) {
        $routeProvider.when('/', {
            templateUrl: 'views/main.html',
            controller: 'MainCtrl'
        });
        // you might need to call $route.reload() if the route changed
        $route.reload();
    });
});

$routeProviderएक के रूप में उपयोग करने के लिए अलियासिंग factory(बाद में उपलब्ध config) सुरक्षा और ऐप सामंजस्य के साथ अच्छी तरह से नहीं खेलेंगे - किसी भी तरह, शांत तकनीक (अपवोट!)।
कोडी

@ क्या आप सुरक्षा / ऐप सामंजस्य नोट की व्याख्या कर सकते हैं? हम एक समान नाव में हैं और उपरोक्त उत्तर जैसा कुछ वास्तव में आसान होगा।
4

2
@virtualandy, यह आम तौर पर एक महान दृष्टिकोण नहीं है क्योंकि आप एक प्रदाता को विभिन्न चरणों में उपलब्ध करा रहे हैं - जो बदले में उच्च-स्तरीय बर्तनों को लीक कर सकता है जिसे कॉन्फ़िगरेशन चरण के भीतर छुपाया जाना चाहिए। मेरा सुझाव यूआई-राउटर को नियोजित करना है (बहुत कठिनाइयों का ख्याल रखना), "रिज़ॉल्यूशन", "कंट्रोलर" और अन्य फ़ंक्शन जैसे टेम्पलेट के लिए फ़ंक्शन के लिए अन्य संकायों का उपयोग करें। मैंने एक "संरक्षित" मॉड्यूल भी बनाया है जिसे मैं साझा कर सकता हूं जो मार्ग योजना के किसी भी हिस्से (टेम्पलेट, टेम्पलेट, नियंत्रक, आदि) को प्रक्षेपित कर सकता है। उपरोक्त समाधान एक अधिक सुरुचिपूर्ण है - लेकिन आपकी प्रमुख चिंताएं क्या हैं?
कोड़ी

1
@virtualandy, यहाँ lazyLoaded टेम्प्लेट, कंट्रोलर, आदि के लिए एक मॉड्यूल है - रिपॉजिट में इसकी माफी नहीं है, लेकिन यहाँ एक फ़िडेल है : jsfiddle.net/cCarlson/zdm6gpnn ... यह लेज़ीवॉल्ड उपरोक्त - और - कुछ भी प्रक्षेपित कर सकता है। URL पैरामीटर के आधार पर। मॉड्यूल कुछ काम का उपयोग कर सकता है, लेकिन कम से कम एक प्रारंभिक बिंदु।
कोडी

@ कोडी - कोई समस्या नहीं, नमूने के लिए धन्यवाद और आगे की व्याख्या। मकसी भाव। हमारे मामले में, हम कोणीय-मार्ग-खंड का उपयोग कर रहे हैं और यह अच्छी तरह से काम कर रहा है। लेकिन अब हमें "गतिशील" मार्गों का समर्थन करने की आवश्यकता है (कुछ deploys में पृष्ठ की पूरी सुविधाएँ / मार्ग नहीं हो सकते हैं, या उनके नाम बदल सकते हैं, आदि) और कुछ JSON में लोड करने की धारणा जो वास्तव में लागू करने से पहले मार्गों को परिभाषित करती है, हमारा विचार था लेकिन .config () के भीतर $ http / $ प्रदाताओं का उपयोग करके समस्याओं में भाग गया।
वर्चुअलंडी

7

$ मार्गप्रोपाइडर यूआरआई पेटेंट में, आप चर मापदंडों को निर्दिष्ट कर सकते हैं, जैसे: $routeProvider.when('/page/:pageNumber' ...और $ मार्गप्रेम के माध्यम से इसे अपने नियंत्रक में एक्सेस कर सकते हैं।

$ मार्ग पृष्ठ के अंत में एक अच्छा उदाहरण है: http://docs.angularjs.org/api/ng.akrune

संपादित करें (संपादित प्रश्न के लिए):

रूटिंग सिस्टम दुर्भाग्य से बहुत सीमित है - इस विषय पर बहुत चर्चा हो रही है, और कुछ समाधान प्रस्तावित किए गए हैं, जैसे कि कई नामित विचार, आदि बनाने के माध्यम से। लेकिन अभी, एनजीएवी निर्देश केवल रूट प्रति एक दृश्य पर कार्य करता है, एक-से-एक आधार। आप इसके बारे में कई तरीकों से जा सकते हैं - सरल एक लोडर के रूप में दृश्य के टेम्पलेट का उपयोग करना होगा, इसमें एक <ng-include src="myTemplateUrl"></ng-include>टैग के साथ ($ गुंजाइश ।myTemplateUrl नियंत्रक में बनाया जाएगा)।

मैं अधिक जटिल (लेकिन क्लीनर, बड़ी और अधिक जटिल समस्याओं के लिए) समाधान का उपयोग करता हूं, मूल रूप से $ मार्ग सेवा को पूरी तरह से छोड़ देता हूं, जो कि यहां विस्तृत है:

http://www.bennadel.com/blog/2420-Mapping-AngularJS-Routes-Onto-URL-Parameters-And-Client-Side-Events.htm


मुझे ng-includeविधि पसंद है। यह वास्तव में सरल है और यह डोम में हेरफेर करने की तुलना में बहुत बेहतर दृष्टिकोण है।
नील

5

निश्चित नहीं है कि यह क्यों काम करता है लेकिन गतिशील (या वाइल्डकार्ड यदि आप चाहें तो) कोणीय 1.2.0-rc.2 में मार्ग संभव हैं ...

http://code.angularjs.org/1.2.0-rc.2/angular.min.js
http://code.angularjs.org/1.2.0-rc.2/angular-route.min.js

angular.module('yadda', [
  'ngRoute'
]).

config(function ($routeProvider, $locationProvider) {
  $routeProvider.
    when('/:a', {
  template: '<div ng-include="templateUrl">Loading...</div>',
  controller: 'DynamicController'
}).


controller('DynamicController', function ($scope, $routeParams) {
console.log($routeParams);
$scope.templateUrl = 'partials/' + $routeParams.a;
}).

example.com/foo -> लोड "फू" आंशिक

example.com/bar-> "बार" आंशिक लोड करता है

एनजी-व्यू में किसी भी समायोजन की आवश्यकता नहीं है। '/: A' केस एकमात्र वैरिएबल है जिसे मैंने पाया है कि यह इसे स्वीकार करेगा .. '/: foo' तब तक काम नहीं करता है जब तक कि आपके हिस्से सभी foo1, foo2 इत्यादि ... '/: a' किसी भी आंशिक के साथ काम न करें। नाम दें।

सभी मान गतिशील नियंत्रक को आग लगाते हैं - इसलिए कोई "अन्यथा" नहीं है, लेकिन मुझे लगता है कि यह वही है जो आप एक गतिशील या वाइल्डकार्ड रूटिंग परिदृश्य में देख रहे हैं।


2

AngularJS 1.1.3 के अनुसार, अब आप बिल्कुल वही कर सकते हैं जो आप नए कैच-ऑल पैरामीटर का उपयोग करके चाहते हैं।

https://github.com/angular/angular.js/commit/7eafbb98c64c0dc079d7d3ec589f1270b7f6fea5

कमिट से:

यह मार्गप्रोवाइडर को उन मापदंडों को स्वीकार करने की अनुमति देता है जो सब्सट्रेट से मेल खाते हैं, भले ही वे स्लैश होते हैं यदि वे एक बृहदान्त्र के बजाय एक तारांकन के साथ उपसर्ग करते हैं। उदाहरण के लिए, जैसे रूट edit/color/:color/largecode/*largecode कुछ इस तरह से मेल खाते हैं http://appdomain.com/edit/color/brown/largecode/code/with/slashs

मैंने खुद इसका परीक्षण किया है (1.1.5 का उपयोग करके) और यह बहुत अच्छा काम करता है। बस ध्यान रखें कि प्रत्येक नया URL आपके नियंत्रक को पुनः लोड करेगा, इसलिए किसी भी प्रकार की स्थिति को बनाए रखने के लिए, आपको एक कस्टम सेवा का उपयोग करने की आवश्यकता हो सकती है।


0

यहाँ एक और उपाय है जो अच्छा काम करता है।

(function() {
    'use strict';

    angular.module('cms').config(route);
    route.$inject = ['$routeProvider'];

    function route($routeProvider) {

        $routeProvider
            .when('/:section', {
                templateUrl: buildPath
            })
            .when('/:section/:page', {
                templateUrl: buildPath
            })
            .when('/:section/:page/:task', {
                templateUrl: buildPath
            });



    }

    function buildPath(path) {

        var layout = 'layout';

        angular.forEach(path, function(value) {

            value = value.charAt(0).toUpperCase() + value.substring(1);
            layout += value;

        });

        layout += '.tpl';

        return 'client/app/layouts/' + layout;

    }

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