मॉड्यूल घोषणा के लिए AngularJS सर्वोत्तम अभ्यास?


115

मेरे पास अपने ऐप में घोषित कोणीय मॉड्यूल का एक गुच्छा है। मैंने मूल रूप से उन्हें इस तरह "जंजीर" वाक्य रचना का उपयोग करके घोषित करना शुरू किया:

angular.module('mymodule', [])
    .controller('myctrl', ['dep1', function(dep1){ ... }])
    .service('myservice', ['dep2', function(dep2){ ... }])
    ... // more here

लेकिन मैंने फैसला किया कि यह पढ़ना बहुत आसान नहीं है, इसलिए मैंने उन्हें इस तरह से मॉड्यूल चर का उपयोग करके घोषित करना शुरू किया:

var mod = angular.module('mymodule', []);

mod.controller('myctrl', ['dep1', function(dep1){ ... }]);

mod.service('myservice', ['dep2', function(dep2){ ... }]);
...

दूसरा सिंटैक्स मेरे लिए बहुत अधिक पठनीय लगता है, लेकिन मेरी एकमात्र शिकायत यह है कि यह सिंटैक्स modवैश्विक दायरे में परिवर्तन को छोड़ देता है । अगर मेरे पास कभी कोई अन्य चर नाम है mod, तो इसे अगले एक (और वैश्विक चर से जुड़े अन्य मुद्दों) के साथ ओवरराइड किया जाएगा।

तो मेरा सवाल यह है कि क्या यह सबसे अच्छा तरीका है? या इस तरह से कुछ करना बेहतर होगा ?:

(function(){
    var mod = angular.module('mymod', []);
    mod.controller('myctrl', ['dep1', function(dep1){ ... }]);
    mod.service('myservice', ['dep2', function(dep2){ ... }]);
    ...
})();

या क्या यह भी परवाह करने के लिए पर्याप्त है? मॉड्यूल घोषणा के लिए "सर्वोत्तम प्रथाओं" क्या हैं, यह जानने के लिए उत्सुक हैं। अग्रिम में धन्यवाद।


3
मैंने एंगुलर बेस्ट प्रैक्टिस के बारे में भी यही सोचा
दलेरजो

जवाबों:


118

मॉड्यूल घोषित करने का 'सर्वश्रेष्ठ' तरीका

जैसे ही कोणीय वैश्विक दायरे में है और मॉड्यूल इसके वैरिएबल में सहेजे जाते हैं, आप इसके माध्यम से मॉड्यूल तक पहुंच सकते हैं angular.module('mymod'):

// one file
// NOTE: the immediately invoked function expression 
// is used to exemplify different files and is not required
(function(){
   // declaring the module in one file / anonymous function
   // (only pass a second parameter THIS ONE TIME as a redecleration creates bugs
   // which are very hard to dedect)
   angular.module('mymod', []);
})();


// another file and/or another anonymous function
(function(){   
 // using the function form of use-strict...
 "use strict";
  // accessing the module in another. 
  // this can be done by calling angular.module without the []-brackets
  angular.module('mymod')
    .controller('myctrl', ['dep1', function(dep1){
      //..
    }])

  // appending another service/controller/filter etc to the same module-call inside the same file
    .service('myservice', ['dep2', function(dep2){ 
    //... 
    }]);

  // you can of course use angular.module('mymod') here as well
  angular.module('mymod').controller('anothermyctrl', ['dep1', function(dep1){
      //..
  }])
})();

किसी अन्य वैश्विक चर की आवश्यकता नहीं है।

बेशक यह सभी वरीयताओं पर निर्भर करता है, लेकिन मुझे लगता है कि यह सबसे अच्छा अभ्यास है

  1. आपको वैश्विक दायरे को प्रदूषित नहीं करना है
  2. आप अपने मॉड्यूल को हर जगह एक्सेस कर सकते हैं और उन्हें और उनके कार्यों को अलग-अलग फ़ाइलों में क्रमबद्ध कर सकते हैं
  3. आप "उपयोग सख्त" के फ़ंक्शन-रूप का उपयोग कर सकते हैं;
  4. फाइलों का लोडिंग ऑर्डर उतना मायने नहीं रखता है

अपने मॉड्यूल और फ़ाइलों को सॉर्ट करने के लिए विकल्प

मॉड्यूल को घोषित करने और एक्सेस करने का यह तरीका आपको बहुत लचीला बनाता है। आप फ़ंक्शन-प्रकार (जैसे किसी अन्य उत्तर में वर्णित) या मार्ग के माध्यम से मॉड्यूल को सॉर्ट कर सकते हैं, जैसे:

/******** sorting by route **********/    
angular.module('home')...
angular.module('another-route')...
angular.module('shared')...

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

/******** modularizing feature-sets **********/
/controllers
/directives
/filters
/services
/my-map-sub-module
/my-map-sub-module/controllers
/my-map-sub-module/services
app.js
...

angular.module('app', [
  'app.directives',
  'app.filters',
  'app.controllers',
  'app.services',
  'myMapSubModule'
]);

angular.module('myMapSubModule',[
   'myMapSubModule.controllers',
   'myMapSubModule.services',
   // only if they are specific to the module
   'myMapSubModule.directives',
   'myMapSubModule.filters'
]);

बहुत बड़ी परियोजनाओं के लिए, मैं कभी-कभी मार्गों द्वारा समूहीकरण मॉड्यूलों को समाप्त करता हूं, जैसा कि ऊपर वर्णित है या कुछ चयनित मुख्य मार्गों या यहां तक ​​कि मार्गों और कुछ चयनित घटकों का एक संयोजन है, लेकिन यह वास्तव में निर्भर करता है।

संपादित करें: सिर्फ इसलिए कि यह संबंधित है और मैं हाल ही में फिर से भाग गया: अच्छी तरह से ध्यान रखें कि आप केवल एक बार एक मॉड्यूल बनाते हैं (कोणीय गति-समारोह में दूसरा पैरामीटर जोड़कर)। यह आपके एप्लिकेशन को गड़बड़ कर देगा और इसका पता लगाना बहुत कठिन हो सकता है।

2015 ईडीआईटी को छाँटने वाले मॉड्यूल पर: डेढ़ साल बाद कोणीय-अनुभव के बाद, मैं यह जोड़ सकता हूं कि आपके ऐप के भीतर अलग-अलग नामित मॉड्यूल का उपयोग करने से लाभ कुछ हद तक सीमित हैं क्योंकि एएमडी अभी भी कोणीय और सेवाओं, निर्देशों और फिल्टर के साथ अच्छी तरह से काम नहीं करता है वैसे भी कोणीय संदर्भ में विश्व स्तर पर उपलब्ध हैं ( जैसा कि यहाँ पर उदाहरण दिया गया है )। हालांकि अभी भी एक शब्दार्थ और संरचनात्मक लाभ है और यह एक मॉड्यूल को शामिल करने में सक्षम हो सकता है / जिसमें कोड की एक पंक्ति के साथ या बाहर टिप्पणी की गई हो।

यह लगभग कभी भी उप-मॉड्यूल को अलग-अलग प्रकार से समझ में नहीं आता है (उदाहरण के लिए 'myMapSubModule.controllers') क्योंकि वे आमतौर पर एक-दूसरे पर निर्भर होते हैं।


7
आप Iife (तुरंत लागू समारोह अभिव्यक्ति), उर्फ गुमनाम स्वयं को क्रियान्वित समारोह की जरूरत नहीं है
plus-

1
आप सही हे। आपको केवल इसकी आवश्यकता है जब आप "सख्त उपयोग करें" के फ़ंक्शन-फॉर्म को लागू करना चाहते हैं; हालांकि चोट नहीं करता है।
ह्यूगो डेर हुनग्रिज

1
ज्यादातर मामलों में आप 'use strict';अपने घटक के अंदर भी रख सकते हैं। module.controller(function () { 'use strict'; ... });
जैक्सन

मुझे क्रियान्वयन पसंद है, लेकिन मुझे या तो चाटने का कोई मज़ा नहीं है, इसलिए मैं इसे मिक्स कर रहा हूं कि बेतेराबा क्या कर रहा है
मिर्को

1
एएमडी का उपयोग करते समय, ऐप नाम का एक एकल मॉड्यूल पर्याप्त है। आवश्यकता कथन को हटाकर एक AMD मॉड्यूल को बाहर कर सकता है। और हमें किसी भी अधिक नियंत्रक और सेवाओं को पंजीकृत करने की आवश्यकता नहीं है।
जेम्स

28

मुझे जॉनपापा द्वारा कोणीय- स्टाइलगाइड पसंद है, और यहां कुछ नियम हैं जो इस प्रश्न से संबंधित हैं:

नियम: नामांकित बनाम बेनामी कार्य

अनाम कार्यों का उपयोग करने से बचें:

// dashboard.js
angular
  .module('app')
  .controller('Dashboard', function() { })

इसके बजाय, नामित कार्यों का उपयोग करें:

// dashboard.js
angular
  .module('app')
  .controller('Dashboard', Dashboard);

function Dashboard() { }

जैसा कि लेखक कहता है: This produces more readable code, is much easier to debug, and reduces the amount of nested callback code.

नियम: प्रति फ़ाइल 1 घटक को परिभाषित करें।

एक फ़ाइल में कई घटकों से बचें:

angular
  .module('app', ['ngRoute'])
  .controller('SomeController', SomeController)
  .factory('someFactory', someFactory);

function SomeController() { }

function someFactory() { }

मॉड्यूल को परिभाषित करने के लिए एक फाइल का उपयोग करें:

// app.module.js
angular
  .module('app', ['ngRoute']);

एक फ़ाइल सिर्फ एक घटक को परिभाषित करने के लिए मॉड्यूल का उपयोग करती है

// someController.js
angular
  .module('app')
  .controller('SomeController', SomeController);

function SomeController() { }

और दूसरे घटक को परिभाषित करने के लिए एक और फ़ाइल

// someFactory.js
angular
  .module('app')
  .factory('someFactory', someFactory);

function someFactory() { }

बेशक, मॉड्यूल, नियंत्रक और सेवाओं के लिए कई अन्य नियम हैं जो काफी उपयोगी और पढ़ने लायक हैं।

और हां_डिमन की टिप्पणी के लिए धन्यवाद, उपरोक्त कोड IIFE में लपेटा जाना चाहिए, उदाहरण के लिए:

(function (window, angular) {
  angular.module('app')
   .controller('Dashboard', function () { });
})(window, window.angular);

अच्छा जवाब और बढ़िया लिंक।
एलेसीडिल

अगर मेरे पास अलग-अलग जावास्क्रिप्ट फ़ाइलों में अलग-अलग नियंत्रक हैं तो इसके लिए अधिक संख्या में फ़ाइलों की लोडिंग की आवश्यकता होती है अर्थात अधिक सर्वर हिट?
विग्नेश सुब्रह्मण्यम

उन्हें मस्त करना / उकसाना / उनका नाम बदलना, गल्प या गुनगुनाना, विग्नेश और व्यक्तिगत रूप से मुझे प्यार करना काफी आसान है।
अक्िंग्सओओ

1
आप जोड़ना भूल गए, कि यह सभी स्निपेट IIFE में होने चाहिए, अन्यथा आपके पास विश्व स्तर पर "someFactory ()" जैसे कार्य हैं। नाम टक्कर के लिए एक मौका है। (और आपको es6 में IIFE की आवश्यकता नहीं है)
ya_dimon

12

मैं हाल ही में इस रूप में अच्छी तरह से किया गया था। मैंने ठीक वैसे ही शुरू किया था जैसे कि आप जंजीर के सिंटैक्स का उपयोग करते हैं, लेकिन लंबे समय में यह बड़ी परियोजनाओं के साथ अनिच्छुक हो जाता है। आम तौर पर मैं एक नियंत्रक मॉड्यूल, एक सेवा मॉड्यूल और इसी तरह अलग-अलग फ़ाइलों में बनाऊंगा और उन्हें किसी अन्य फ़ाइल में पाए गए मेरे मुख्य एप्लिकेशन मॉड्यूल में इंजेक्ट करूंगा। उदाहरण के लिए:

// My Controllers File
angular.module('my-controllers',[])
    .controller('oneCtrl',[...])
    .controller('twoCtrl',[...]);

// My Services File
angular.module('my-services',[])
    .factory('oneSrc',[...])
    .facotry('twoSrc',[...]);

// My Directives File
angular.module('my-directives',[])
    .directive('oneDrct',[...])
    .directive('twoDrct',[...]);

// My Main Application File
angular.module('my-app',['my-controllers','my-services','my-directives',...]);

लेकिन इन फाइलों में से हर एक के बड़े होने का रास्ता साफ हो रहा था। इसलिए मैंने उन्हें प्रत्येक नियंत्रक या सेवा के आधार पर अलग-अलग फाइलों में तोड़ने का फैसला किया। मैंने पाया कि angular.module('mod-name').इंजेक्शन सरणी के बिना उपयोग करना , क्या आपको इसके लिए काम करने की आवश्यकता है। एक फ़ाइल में एक वैश्विक चर की घोषणा करना और उम्मीद करना कि दूसरे में आसानी से उपलब्ध होना बस काम नहीं करता है या अप्रत्याशित परिणाम हो सकता है।

तो संक्षेप में मेरे आवेदन कुछ इस तरह से देखा:

// Main Controller File
angular.module('my-controllers',[]);

// Controller One File
angular.module('my-controllers').controller('oneCtrl',[...]);

//Controller Two File
angular.module('my-controllers').controller('twoCtrl',[...]);

मैंने यह सेवा फ़ाइल के लिए भी किया है, मुख्य एप्लिकेशन मॉड्यूल फ़ाइल को बदलने की कोई आवश्यकता नहीं है जो आप अभी भी उसी मॉड्यूल को इंजेक्ट कर रहे हैं।


1
सेवाओं / निर्देशों / नियंत्रकों के लिए अलग मॉड्यूल बनाने की बात क्या है?
फिलिप सोबाकक

2
बड़ी परियोजनाओं में नियंत्रक / फिल्टर / निर्देश / सेवाओं के एक साथ इंटरएक्टिव होने पर चीजों को खोजना मुश्किल हो सकता है। यह चीजों को व्यवस्थित रखने का सिर्फ एक तरीका है।
meconroy

1
@FilipSobczak वह सेवाओं / निर्देशों / नियंत्रकों के लिए अलग मॉड्यूल नहीं बना रहा है। बल्कि, उन्होंने केवल एक बार उपयोग करके मॉड्यूल बनाया है angular.module('my-controllers',[]);(ध्यान दें कि वह घोषणा के लिए केवल एक बार [] निर्दिष्ट कर रहा है)। वह बस अन्य फ़ाइलों में इस पुन: उपयोग कर रहा है। फ़ाइलों को अलग करना परियोजना को बनाए रखना अपेक्षाकृत आसान बनाता है, विशेष रूप से बड़े लोगों को।
डेनेर

8

एक अन्य अभ्यास नियंत्रकों, निर्देशों आदि को अपने स्वयं के मॉड्यूल में सामान करना है और उन मॉड्यूल को अपने "मुख्य" में इंजेक्ट करना है:

angular.module('app.controllers', [])
  .controller('controller1', ['$scope', function (scope) {
    scope.name = "USER!";
  }]);

angular.module('app.directives', [])
  .directive('myDirective', [function () {
    return {
      restrict: 'A',
      template: '<div>my directive!</div>'
    }
  }]);

angular.module('app', [
  'app.controllers',
  'app.directives'
]);

वैश्विक दायरे में कुछ भी नहीं बचा है।

http://plnkr.co/edit/EtzzPRyxWT1MkhK7KcLo?p=preview


क्यों आप मॉड्यूल नाम app.controllersके controllersरूप में इस्तेमाल कर रहे हैं , क्या कोई फायदा है? मैं एंगुलरज में एक नवागंतुक हूं
सिजो वीजन

4

मुझे अपनी फ़ाइलें और मेरे मॉड्यूल विभाजित करना पसंद है।

कुछ इस तरह:

app.js

var myApp = angular.module('myApp', ['myApp.controllers', 'myApp.directives', 'myApp.services']);

myApp.config(['$routeProvider', function($routeProvider) {
    /* routes configs */
    $routeProvider.when(/*...*/);
}]);

directives.js

var myDirectives = angular.module('myApp.directives', []);

myDirectives.directive( /* ... */ );

service.js

var myServices = angular.module('myApp.services', []);

myServices.factory( /* ... */ );

Im "जंजीर शैली" का एक बड़ा प्रशंसक नहीं है, इसलिए मैं हमेशा अपने चर को लिखना पसंद करता हूं।


2
यह वह तरीका है जो मैं यह कर रहा था, लेकिन प्रत्येक सेवाएं.जेएस या कंट्रोलर। जेएस फाइल बड़े पैमाने पर प्रोजेक्ट में बड़ी तेजी से मिलती है, अंततः आपको प्रत्येक सेवा या नियंत्रक को एक अलग फाइल से बाहर करने की आवश्यकता होगी।
मेकोनारियो

1
@meconroy बिल्कुल। जब बात बड़ी और बड़ी हो जाती है, तो मैं निर्देश को छोटे मॉड्यूल में तोड़ना पसंद करता हूं और फिर "मुख्य" निर्देशात्मक मॉड्यूल को इंजेक्ट करता हूं।
बेतराबा

1

मैं Angularjs स्टाइल गाइड का पालन करने का सुझाव देता हूं ।
वे नामकरण सम्मेलन से सभी अवधारणा को संभालते हैं, ताकि आपके ऐप को संशोधित किया जा सके।

कोणीय 2 के लिए, आप कोणीय 2 स्टाइल गाइड की जांच कर सकते हैं


0

मेरे लिए, चाइनिंग सबसे कॉम्पैक्ट तरीका है:

angular.module("mod1",["mod1.submod1"])

 .value("myValues", {
   ...
 })

 .factory("myFactory", function(myValues){
   ...
 })

 .controller("MainCtrl", function($scope){

   // when using "Ctrl as" syntax
   var MC = this;
   MC.data = ...;
 })
 ;

इस तरह मैं आसानी से मॉड्यूल के बीच घटकों को स्थानांतरित कर सकता हूं, कभी भी एक ही मॉड्यूल को दो बार घोषित करने की आवश्यकता नहीं है, कभी भी किसी वैश्विक चर की आवश्यकता नहीं है।

और अगर फ़ाइल बहुत लंबी हो जाती है, तो समाधान सरल है - दो फ़ाइलों में विभाजित करें, प्रत्येक शीर्ष पर अपना मॉड्यूल घोषित करता है। अधिक पारदर्शिता के लिए, मैं प्रति फ़ाइल एक अद्वितीय मॉड्यूल रखने की कोशिश करता हूं और इसे फ़ाइल के पूर्ण पथ से मिलता-जुलता नाम देता हूं। इस तरह से भी मुझे बिना मॉड्यूल के लिखने की आवश्यकता नहीं है [], जो कि एक सामान्य दर्द बिंदु है।

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