विभाजन और टेम्पलेट्स के जटिल घोंसले के शिकार


503

मेरा प्रश्न के जटिल घोंसले से निपटने के बारे में जाने के लिए कैसे शामिल टेम्पलेट्स (भी बुलाया partials एक AngularJS आवेदन में)।

मेरी स्थिति का वर्णन करने का सबसे अच्छा तरीका एक छवि है जिसे मैंने बनाया है:

AngularJS पेज आरेख

जैसा कि आप देख सकते हैं यह बहुत सारे नेस्टेड मॉडल के साथ एक काफी जटिल अनुप्रयोग होने की क्षमता है।

एप्लिकेशन एकल-पृष्ठ है, इसलिए यह एक इंडेक्स। Html को लोड करता है जिसमें ng-viewविशेषता के साथ DOM में एक div एलिमेंट होता है ।

सर्कल 1 के लिए , आप देखते हैं कि एक प्राथमिक नेविगेशन है जो उपयुक्त टेम्प्लेट को लोड करता है ng-view। मैं $routeParamsमुख्य ऐप मॉड्यूल को पास करके ऐसा कर रहा हूं । यहाँ एक उदाहरण है कि मेरे ऐप में क्या है:

angular.module('myApp', []).
    config(['$routeProvider', function($routeProvider) {
        $routeProvider.                     
            when("/job/:jobId/zones/:zoneId", { controller: JobDetailController, templateUrl: 'assets/job_list_app/templates/zone_edit.html' }).
            when("/job/:jobId/initial_inspection", { controller: JobDetailController, templateUrl: 'assets/job_list_app/templates/initial_inspection.html' }).
            when("/job/:jobId/zones/:zoneId/rooms/:roomId", { controller: JobDetailController, templateUrl: 'assets/job_list_app/templates/room_edit.html' })       

    }]);

सर्कल 2 में , जो टेम्पलेट लोड किया गया ng-viewहै , उसमें एक अतिरिक्त उप-नेविगेशन है । इस उप-नौसेना को तब इसके नीचे के क्षेत्र में टेम्प्लेट लोड करने की आवश्यकता होती है - लेकिन चूंकि एनजी-व्यू का उपयोग पहले से ही किया जा रहा है, मुझे यकीन नहीं है कि यह कैसे करना है।

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

सर्कल 3 में , आप देख सकते हैं कि चीजें और भी जटिल हो सकती हैं। ऐसी संभावना है कि उप-नेविगेशन टेम्प्लेट में एक दूसरा उप-नेविगेशन होगा जिसे अपने स्वयं के टेम्प्लेट को लोड करने की आवश्यकता होगी और साथ ही 4 के क्षेत्र में

सभी को एक दूसरे से अलग रखते हुए टेम्प्लेट के ऐसे जटिल घोंसले से निपटने के लिए एक AngularJS ऐप को कैसे तैयार किया जाता है?


3
यदि आप अभी भी इस थ्रेड का अनुसरण कर रहे हैं, तो मैंने इसे संबोधित करने के लिए एक नए AngularUI प्रोजेक्ट का लिंक जोड़ा और एक तीसरा डेमो जो मेरे जवाब के लिए एक निर्देश की आवश्यकता के बिना सबरूट द्वारा संचालित है।
प्रोलेसर

2
और इसका क्या? bennadel.com/blog/…
ericbae

82
सबसे लंबा सवाल जो मैंने लंबे समय में देखा है :)
मार्क नाडिग

2
माना! मॉकअप
ब्रायन होंग

4
यहां प्रश्न में सीधे विकल्पों के लिंक जोड़ना बहुत अच्छा होगा। github.com/angular-ui/ui-router github.com/artch/angular-route-segment github.com/dotJEM/angular-rout
जेन्स

जवाबों:


171

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

EDIT यहां कुछ उदाहरण छद्म कोड दिए गए हैं जिनसे आप अंदाजा लगा सकते हैं कि मैं किस बारे में बात कर रहा हूं। एक नेस्टेड उप नेविगेशन के साथ।

यहाँ मुख्य ऐप पेज है

<!-- primary nav -->
<a href="#/page/1">Page 1</a>
<a href="#/page/2">Page 2</a>
<a href="#/page/3">Page 3</a>

<!-- display the view -->
<div ng-view>
</div>

उप नेविगेशन के लिए निर्देश

app.directive('mySubNav', function(){
    return {
        restrict: 'E',
        scope: {
           current: '=current'
        },
        templateUrl: 'mySubNav.html',
        controller: function($scope) {
        }
    };
});

उप नेविगेशन के लिए टेम्पलेट

<a href="#/page/1/sub/1">Sub Item 1</a>
<a href="#/page/1/sub/2">Sub Item 2</a>
<a href="#/page/1/sub/3">Sub Item 3</a>

मुख्य पृष्ठ के लिए टेम्पलेट (प्राथमिक नौसेना से)

<my-sub-nav current="sub"></my-sub-nav>

<ng-switch on="sub">
  <div ng-switch-when="1">
      <my-sub-area1></my-sub-area>
  </div>
  <div ng-switch-when="2">
      <my-sub-area2></my-sub-area>
  </div>
  <div ng-switch-when="3">
      <my-sub-area3></my-sub-area>
  </div>
</ng-switch>

मुख्य पृष्ठ के लिए नियंत्रक। (प्राथमिक नौसेना से)

app.controller('page1Ctrl', function($scope, $routeParams) {
     $scope.sub = $routeParams.sub;
});

एक उप क्षेत्र के लिए निर्देश

app.directive('mySubArea1', function(){
    return {
        restrict: 'E',
        templateUrl: 'mySubArea1.html',
        controller: function($scope) {
            //controller for your sub area.
        }
    };
});

9
मुझे प्रोलेसर का समाधान बेहतर लगता है, हम अपने ऐप पर ऐसा कुछ करते हैं और यह ठीक काम करता है। मांस के समाधान के साथ समस्या नियंत्रक कोड के निर्देशों में जा रही है। आमतौर पर नियंत्रक जिसे आप एक निर्देश में निर्दिष्ट करते हैं, वह है जो पूर्व के निर्देश के साथ मिलकर काम करता है: ngModelCtrl जो इनपुट और अन्य निर्देशों के साथ मिलकर काम करता है। आपके मामले में एक निर्देश के भीतर नियंत्रक कोड डालना एक कोड गंध होगा, यह वास्तव में एक स्वतंत्र नियंत्रक है।
क्रिसऑडनी

@ पत्थर, अच्छा! यह वास्तव में अच्छा समझा गया है, लेकिन एक अच्छे जेएस प्रोग्रामर और एंगुलरजेएस में शुरुआत करने वाले के रूप में मैं उस अच्छी तरह से पकड़ लेता हूं ... मुझे और समुदाय को वास्तव में उस दृष्टिकोण का उपयोग करके एक कार्यशील नमूने के लिए जेएसफल्ड लिंक का आनंद मिलेगा। आस-पास इसे समझना आसान होगा! :) धन्यवाद
रोजर बैरेटो

8
मुझे लगता है कि यह समाधान किसी भी तरह के 'नेस्टेड व्यू काम नहीं करता' के लिए पहला उत्तर होना चाहिए। सिर्फ इसलिए कि यह ui- राउटर और आदि धन्यवाद का उपयोग करने के बजाय कोणीय विचारधारा के बहुत करीब है।
सर्गेई पैनफिलोव

तो उत्तर है निर्देश?
मार्क एम।

सब- नेवी आइटम्स को हाइलाइट करने के लिए आप इसका उपयोग कर सकते हैं: coder1.com/articles/angularjs-managing-active-nav-elements क्या यह इसे करने का एक अच्छा तरीका है?
बच गए

198

अद्यतन: इस समस्या को हल करने के लिए AngularUI की नई परियोजना देखें


उपखंडों के लिए यह एनजी में शामिल तार का उपयोग करना जितना आसान है:

<ul id="subNav">
  <li><a ng-click="subPage='section1/subpage1.htm'">Sub Page 1</a></li>
  <li><a ng-click="subPage='section1/subpage2.htm'">Sub Page 2</a></li>
  <li><a ng-click="subPage='section1/subpage3.htm'">Sub Page 3</a></li>
</ul>
<ng-include src="subPage"></ng-include>

या यदि आप सभी जगह उप पृष्ठों के लिंक हैं, तो आप एक वस्तु बना सकते हैं:

$scope.pages = { page1: 'section1/subpage1.htm', ... };
<ul id="subNav">
  <li><a ng-click="subPage='page1'">Sub Page 1</a></li>
  <li><a ng-click="subPage='page2'">Sub Page 2</a></li>
  <li><a ng-click="subPage='page3'">Sub Page 3</a></li>
</ul>
<ng-include src="pages[subPage]"></ng-include>

या आप भी उपयोग कर सकते हैं $routeParams

$routeProvider.when('/home', ...);
$routeProvider.when('/home/:tab', ...);
$scope.params = $routeParams;
<ul id="subNav">
  <li><a href="#/home/tab1">Sub Page 1</a></li>
  <li><a href="#/home/tab2">Sub Page 2</a></li>
  <li><a href="#/home/tab3">Sub Page 3</a></li>
</ul>
<ng-include src=" '/home/' + tab + '.html' "></ng-include>

आप प्रत्येक आंशिक के सबसे ऊपरी स्तर पर एक एनजी-नियंत्रक भी रख सकते हैं


8
मुझे आपका समाधान बेहतर लगा। मैं कोणीय के लिए एक newb हूँ और यह बहुत अधिक समझ में आता है कि मैं आज तक वेब कैसे देखता हूं। कौन जानता है, मांस यह करने के लिए कोणीय ढांचे का अधिक उपयोग कर सकता है, लेकिन ऐसा लगता है जैसे आपने इसे अधिक समझदार तरीके से कोड की कम पंक्तियों के साथ इसका नामकरण किया है। धन्यवाद!
21

2
@ProLooser शायद आपका मतलब था कि यह लिंक github.com/angular-ui/ui-router ... आपके द्वारा चिपकाया गया एक टूटा हुआ है
simonC

4
मैं ओपी के रूप में एक ही डिजाइन मुद्दा रहा हूँ। क्या किसी ने AngularUI राज्य तंत्र की कोशिश की है? मैं अभी तक एक और तीसरे पक्ष के पुस्तकालय का उपयोग करने के लिए काफी अनिच्छुक हूं और मैं एंगुलरजेएस के साथ 'चीजों को करने का तरीका' के साथ रहना चाहूंगा। लेकिन दूसरी ओर, राउटिंग सिस्टम इसकी अकिलीज़ हील लगता है ... @PhillipKregg, इस परिदृश्य को हल करने के लिए आपने क्या किया?
सैम

4
आप <div ng-include="'/home/' + tab + '.html'" ng-controller="SubCtrl"></div>उप-टेम्पलेट के लिए एक अलग नियंत्रक / गुंजाइश का उपयोग करने के लिए निर्दिष्ट कर सकते हैं । या ngControllerप्रत्येक आंशिक के लिए एक अलग नियंत्रक का उपयोग करने के लिए अपने उप-टेम्पलेट (ओं) के भीतर कहीं भी निर्देश निर्दिष्ट करें ।
कॉलिन

2
@DerekAdair परियोजना काफी स्थिर है (संस्करण संख्या के बावजूद) और कुछ स्थानों पर उत्पादन में उपयोग में है। यह अनावश्यक नियंत्रक लोडिंग को रोकता है, और मेरे सुझाए गए समाधान का एक बेहतर विकल्प है।
प्रोलसर

26

आप इस पुस्तकालय को उसी उद्देश्य के लिए भी देख सकते हैं:

http://angular-route-segment.com

ऐसा लगता है कि आप क्या देख रहे हैं, और यह यूआई-राउटर की तुलना में उपयोग करने के लिए बहुत सरल है। से डेमो साइट :

जे एस:

$routeSegmentProvider.

when('/section1',          's1.home').
when('/section1/:id',      's1.itemInfo.overview').
when('/section2',          's2').

segment('s1', {
    templateUrl: 'templates/section1.html',
    controller: MainCtrl}).
within().
    segment('home', {
        templateUrl: 'templates/section1/home.html'}).
    segment('itemInfo', {
        templateUrl: 'templates/section1/item.html',
        controller: Section1ItemCtrl,
        dependencies: ['id']}).
    within().
        segment('overview', {
            templateUrl: 'templates/section1/item/overview.html'}).

शीर्ष-स्तरीय HTML:

<ul>
    <li ng-class="{active: $routeSegment.startsWith('s1')}">
        <a href="/section1">Section 1</a>
    </li>
    <li ng-class="{active: $routeSegment.startsWith('s2')}">
        <a href="/section2">Section 2</a>
    </li>
</ul>
<div id="contents" app-view-segment="0"></div>

नेस्टेड HTML:

<h4>Section 1</h4>
Section 1 contents.
<div app-view-segment="1"></div>

Artem, आपका अब तक का सबसे अच्छा समाधान है! मैं इस तथ्य को पसंद करता हूं कि आप कोणीय मार्ग का विस्तार करते हैं बजाय इसे कोणीय ui करता है।
LastTribunal

17

मैं भी एंगुलर में नेस्टेड विचारों से जूझ रहा था।

एक बार जब मुझे यूआई-राउटर की पकड़ मिल गई तो मुझे पता था कि मैं कभी भी कोणीय डिफ़ॉल्ट रूटिंग कार्यक्षमता पर वापस नहीं जाऊंगा।

यहाँ एक उदाहरण अनुप्रयोग है जो कई स्तरों के दृश्यों का उपयोग करता है

app.config(function ($stateProvider, $urlRouterProvider,$httpProvider) {
// navigate to view1 view by default
$urlRouterProvider.otherwise("/view1");

$stateProvider
    .state('view1', {
        url: '/view1',
        templateUrl: 'partials/view1.html',
        controller: 'view1.MainController'
    })
    .state('view1.nestedViews', {
        url: '/view1',
        views: {
            'childView1': { templateUrl: 'partials/view1.childView1.html' , controller: 'childView1Ctrl'},
            'childView2': { templateUrl: 'partials/view1.childView2.html', controller: 'childView2Ctrl' },
            'childView3': { templateUrl: 'partials/view1.childView3.html', controller: 'childView3Ctrl' }
        }
    })

    .state('view2', {
        url: '/view2',
    })

    .state('view3', {
        url: '/view3',
    })

    .state('view4', {
        url: '/view4',
    });
});

जैसा कि देखा जा सकता है कि 4 मुख्य दृश्य हैं (view1, view2, view3, view4) और view1 में 3 बच्चे दृश्य हैं।


2
इंजेक्शन लगाने का उद्देश्य क्या है $httpProvider? मैं इसे कहीं भी इस्तेमाल नहीं करते।
आरोन

@Aaron app.config कोड के इस टुकड़े में समाप्त नहीं होता है और $ httpProvider कहीं और इस्तेमाल किया जा सकता है
व्लाद

4

नेस्टेड एनजी-व्यू का उपयोग करने से बचने के लिए आप एनजी-इन का उपयोग कर सकते हैं।

http://docs.angularjs.org/api/ng/directive/ngInclude
http://plnkr.co/edit/ngdoc:example-example39@snapshot?p=preview

मेरा अनुक्रमणिका पृष्ठ मैं एनजी-व्यू का उपयोग करता हूं। फिर मेरे उप पृष्ठों पर जो मुझे नेस्टेड फ्रेम करने की आवश्यकता है। मैं एनजी शामिल का उपयोग करें। डेमो एक ड्रॉपडाउन दिखाता है। मैंने एक लिंक एनजी-क्लिक के साथ मेरा स्थान लिया। फ़ंक्शन में मैं $ गुंजाइश लगाऊंगा ।emplate = $ गुंजाइश.templates [0]; या $ गुंजाइश .emplate = $ गुंजाइश.templates [1];

$scope.clickToSomePage= function(){
  $scope.template = $scope.templates[0];
};

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